diff --git a/CHANGELOG.md b/CHANGELOG.md index ce2b472..ef4c674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security - In case of vulnerabilities. +## [1.0.12-alfa] + +### Added +- Added Catalog functionality + +### Changed +- For changes in existing functionality. + +### Deprecated +- For soon-to-be removed features. + +### Removed +- For now removed features. + +### Fixed +- Set default language when registering Documents or URLs. + +### Security +- In case of vulnerabilities. + ## [1.0.11-alfa] ### Added diff --git a/common/models/document.py b/common/models/document.py index e1a2535..7d08e67 100644 --- a/common/models/document.py +++ b/common/models/document.py @@ -21,17 +21,17 @@ class Catalog(db.Model): min_chunk_size = db.Column(db.Integer, nullable=True, default=2000) max_chunk_size = db.Column(db.Integer, nullable=True, default=3000) - # Embedding search variables - es_k = db.Column(db.Integer, nullable=True, default=5) - es_similarity_threshold = db.Column(db.Float, nullable=True, default=0.7) + # Embedding search variables ==> move to specialist? + es_k = db.Column(db.Integer, nullable=True, default=8) + es_similarity_threshold = db.Column(db.Float, nullable=True, default=0.4) - # Chat variables + # Chat variables ==> Move to Specialist? chat_RAG_temperature = db.Column(db.Float, nullable=True, default=0.3) chat_no_RAG_temperature = db.Column(db.Float, nullable=True, default=0.5) # Tuning enablers embed_tuning = db.Column(db.Boolean, nullable=True, default=False) - rag_tuning = db.Column(db.Boolean, nullable=True, default=False) + rag_tuning = db.Column(db.Boolean, nullable=True, default=False) # Move to Specialist? # Versioning Information created_at = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) @@ -42,6 +42,7 @@ class Catalog(db.Model): class Document(db.Model): id = db.Column(db.Integer, primary_key=True) + # tenant_id = db.Column(db.Integer, db.ForeignKey(Tenant.id), nullable=False) catalog_id = db.Column(db.Integer, db.ForeignKey(Catalog.id), nullable=True) name = db.Column(db.String(100), nullable=False) valid_from = db.Column(db.DateTime, nullable=True) diff --git a/common/utils/document_utils.py b/common/utils/document_utils.py index dbe701c..3ac4dbd 100644 --- a/common/utils/document_utils.py +++ b/common/utils/document_utils.py @@ -22,7 +22,7 @@ def create_document_stack(api_input, file, filename, extension, tenant_id): db.session.add(new_doc) # Create the DocumentVersion - new_doc_vers = create_version_for_document(new_doc, + new_doc_vers = create_version_for_document(new_doc, tenant_id, api_input.get('url', ''), api_input.get('language', 'en'), api_input.get('user_context', ''), @@ -63,7 +63,7 @@ def create_document(form, filename, catalog_id): return new_doc -def create_version_for_document(document, url, language, user_context, user_metadata): +def create_version_for_document(document, tenant_id, url, language, user_context, user_metadata): new_doc_vers = DocumentVersion() if url != '': new_doc_vers.url = url @@ -83,7 +83,7 @@ def create_version_for_document(document, url, language, user_context, user_meta set_logging_information(new_doc_vers, dt.now(tz.utc)) - mark_tenant_storage_dirty(document.tenant_id) + mark_tenant_storage_dirty(tenant_id) return new_doc_vers @@ -287,7 +287,7 @@ def edit_document_version(version_id, user_context): return None, str(e) -def refresh_document_with_info(doc_id, api_input): +def refresh_document_with_info(doc_id, tenant_id, api_input): doc = Document.query.get_or_404(doc_id) old_doc_vers = DocumentVersion.query.filter_by(doc_id=doc_id).order_by(desc(DocumentVersion.id)).first() @@ -295,11 +295,11 @@ def refresh_document_with_info(doc_id, api_input): return None, "This document has no URL. Only documents with a URL can be refreshed." new_doc_vers = create_version_for_document( - doc, + doc, tenant_id, old_doc_vers.url, api_input.get('language', old_doc_vers.language), api_input.get('user_context', old_doc_vers.user_context), - api_input.get('user_metadata', old_doc_vers.user_metadata) + api_input.get('user_metadata', old_doc_vers.user_metadata), ) set_logging_information(new_doc_vers, dt.now(tz.utc)) @@ -329,7 +329,7 @@ def refresh_document_with_info(doc_id, api_input): # Update the existing refresh_document function to use the new refresh_document_with_info -def refresh_document(doc_id): +def refresh_document(doc_id, tenant_id): current_app.logger.info(f'Refreshing document {doc_id}') doc = Document.query.get_or_404(doc_id) old_doc_vers = DocumentVersion.query.filter_by(doc_id=doc_id).order_by(desc(DocumentVersion.id)).first() @@ -340,7 +340,7 @@ def refresh_document(doc_id): 'user_metadata': old_doc_vers.user_metadata } - return refresh_document_with_info(doc_id, api_input) + return refresh_document_with_info(doc_id, tenant_id, api_input) # Function triggered when a document_version is created or updated diff --git a/common/utils/model_utils.py b/common/utils/model_utils.py index 6f6fde1..aecb12a 100644 --- a/common/utils/model_utils.py +++ b/common/utils/model_utils.py @@ -14,7 +14,7 @@ from portkey_ai.langchain.portkey_langchain_callback_handler import LangchainCal from common.langchain.llm_metrics_handler import LLMMetricsHandler from common.langchain.tracked_openai_embeddings import TrackedOpenAIEmbeddings from common.langchain.tracked_transcribe import tracked_transcribe -from common.models.document import EmbeddingSmallOpenAI, EmbeddingLargeOpenAI +from common.models.document import EmbeddingSmallOpenAI, EmbeddingLargeOpenAI, Catalog from common.models.user import Tenant from config.model_config import MODEL_CONFIG from common.utils.business_event_context import current_event @@ -42,8 +42,9 @@ def set_language_prompt_template(cls, language_prompt): class ModelVariables(MutableMapping): - def __init__(self, tenant: Tenant): + def __init__(self, tenant: Tenant, catalog_id=None): self.tenant = tenant + self.catalog_id = catalog_id self._variables = self._initialize_variables() self._embedding_model = None self._llm = None @@ -57,25 +58,32 @@ class ModelVariables(MutableMapping): def _initialize_variables(self): variables = {} - # We initialize the variables that are available knowing the tenant. For the other, we will apply 'lazy loading' - variables['k'] = self.tenant.es_k or 5 - variables['similarity_threshold'] = self.tenant.es_similarity_threshold or 0.7 - variables['RAG_temperature'] = self.tenant.chat_RAG_temperature or 0.3 - variables['no_RAG_temperature'] = self.tenant.chat_no_RAG_temperature or 0.5 - variables['embed_tuning'] = self.tenant.embed_tuning or False - variables['rag_tuning'] = self.tenant.rag_tuning or False + # Get the Catalog if catalog_id is passed + if self.catalog_id: + catalog = Catalog.query.get_or_404(self.catalog_id) + + # We initialize the variables that are available knowing the tenant. + variables['embed_tuning'] = catalog.embed_tuning or False + + # Set HTML Chunking Variables + variables['html_tags'] = catalog.html_tags + variables['html_end_tags'] = catalog.html_end_tags + variables['html_included_elements'] = catalog.html_included_elements + variables['html_excluded_elements'] = catalog.html_excluded_elements + variables['html_excluded_classes'] = catalog.html_excluded_classes + + # Set Chunk Size variables + variables['min_chunk_size'] = catalog.min_chunk_size + variables['max_chunk_size'] = catalog.max_chunk_size + + # Set the RAG Context (will have to change once specialists are defined variables['rag_context'] = self.tenant.rag_context or " " - - # Set HTML Chunking Variables - variables['html_tags'] = self.tenant.html_tags - variables['html_end_tags'] = self.tenant.html_end_tags - variables['html_included_elements'] = self.tenant.html_included_elements - variables['html_excluded_elements'] = self.tenant.html_excluded_elements - variables['html_excluded_classes'] = self.tenant.html_excluded_classes - - # Set Chunk Size variables - variables['min_chunk_size'] = self.tenant.min_chunk_size - variables['max_chunk_size'] = self.tenant.max_chunk_size + # Temporary setting until we have Specialists + variables['rag_tuning'] = False + variables['RAG_temperature'] = 0.3 + variables['no_RAG_temperature'] = 0.5 + variables['k'] = 8 + variables['similarity_threshold'] = 0.4 # Set model providers variables['embedding_provider'], variables['embedding_model'] = self.tenant.embedding_model.rsplit('.', 1) @@ -195,7 +203,12 @@ class ModelVariables(MutableMapping): return self.transcription_client elif key in self._variables.get('prompt_templates', []): return self.get_prompt_template(key) - return self._variables.get(key) + else: + value = self._variables.get(key) + if value is not None: + return value + else: + raise KeyError(f'Variable {key} does not exist in ModelVariables') def __setitem__(self, key: str, value: Any) -> None: self._variables[key] = value @@ -225,8 +238,8 @@ class ModelVariables(MutableMapping): return self._variables.values() -def select_model_variables(tenant): - model_variables = ModelVariables(tenant=tenant) +def select_model_variables(tenant, catalog_id=None): + model_variables = ModelVariables(tenant=tenant, catalog_id=catalog_id) return model_variables diff --git a/eveai_api/api/document_api.py b/eveai_api/api/document_api.py index befcbb3..47728c9 100644 --- a/eveai_api/api/document_api.py +++ b/eveai_api/api/document_api.py @@ -217,7 +217,8 @@ class DocumentResource(Resource): @document_ns.response(200, 'Document refreshed successfully') def post(self, document_id): """Refresh a document""" - new_version, result = refresh_document(document_id) + tenant_id = get_jwt_identity() + new_version, result = refresh_document(document_id, tenant_id) if new_version: return {'message': f'Document refreshed. New version: {new_version.id}. Task ID: {result}'}, 200 else: diff --git a/eveai_app/templates/document/catalogs.html b/eveai_app/templates/document/catalogs.html index 513c216..a81daa4 100644 --- a/eveai_app/templates/document/catalogs.html +++ b/eveai_app/templates/document/catalogs.html @@ -13,6 +13,7 @@ {{ render_selectable_table(headers=["Catalog ID", "Name"], rows=rows, selectable=True, id="catalogsTable") }}
+
diff --git a/eveai_app/templates/navbar.html b/eveai_app/templates/navbar.html index a2e5443..bb11f33 100644 --- a/eveai_app/templates/navbar.html +++ b/eveai_app/templates/navbar.html @@ -81,6 +81,8 @@ {% endif %} {% if current_user.is_authenticated %} {{ dropdown('Document Mgmt', 'note_stack', [ + {'name': 'Add Catalog', 'url': '/document/catalog', 'roles': ['Super User', 'Tenant Admin']}, + {'name': 'All Catalogs', 'url': '/document/catalogs', 'roles': ['Super User', 'Tenant Admin']}, {'name': 'Add Document', 'url': '/document/add_document', 'roles': ['Super User', 'Tenant Admin']}, {'name': 'Add URL', 'url': '/document/add_url', 'roles': ['Super User', 'Tenant Admin']}, {'name': 'Add a list of URLs', 'url': '/document/add_urls', 'roles': ['Super User', 'Tenant Admin']}, @@ -114,6 +116,17 @@ {% endif %} {% if current_user.is_authenticated %} +
@@ -78,27 +63,6 @@
- -
- {% set html_fields = ['html_tags', 'html_end_tags', 'html_included_elements', 'html_excluded_elements', 'html_excluded_classes', 'min_chunk_size', 'max_chunk_size'] %} - {% for field in form %} - {{ render_included_field(field, disabled_fields=[], include_fields=html_fields) }} - {% endfor %} -
- -
- {% set es_fields = ['es_k', 'es_similarity_threshold', ] %} - {% for field in form %} - {{ render_included_field(field, disabled_fields=[], include_fields=es_fields) }} - {% endfor %} -
- -
- {% set tuning_fields = ['embed_tuning', 'rag_tuning', ] %} - {% for field in form %} - {{ render_included_field(field, disabled_fields=[], include_fields=tuning_fields) }} - {% endfor %} -
diff --git a/eveai_app/views/document_views.py b/eveai_app/views/document_views.py index 2d432e6..76060e8 100644 --- a/eveai_app/views/document_views.py +++ b/eveai_app/views/document_views.py @@ -63,6 +63,16 @@ def catalog(): tenant_id = session.get('tenant').get('id') new_catalog = Catalog() form.populate_obj(new_catalog) + # Handle Embedding Variables + new_catalog.html_tags = [tag.strip() for tag in form.html_tags.data.split(',')] if form.html_tags.data else [] + new_catalog.html_end_tags = [tag.strip() for tag in form.html_end_tags.data.split(',')] \ + if form.html_end_tags.data else [] + new_catalog.html_included_elements = [tag.strip() for tag in form.html_included_elements.data.split(',')] \ + if form.html_included_elements.data else [] + new_catalog.html_excluded_elements = [tag.strip() for tag in form.html_excluded_elements.data.split(',')] \ + if form.html_excluded_elements.data else [] + new_catalog.html_excluded_classes = [cls.strip() for cls in form.html_excluded_classes.data.split(',')] \ + if form.html_excluded_classes.data else [] set_logging_information(new_catalog, dt.now(tz.utc)) try: @@ -75,13 +85,11 @@ def catalog(): flash(f'Failed to add catalog. Error: {e}', 'danger') current_app.logger.error(f'Failed to add catalog {new_catalog.name}' f'for tenant {tenant_id}. Error: {str(e)}') - else: - flash('Please fill in all required fields.', 'information') - return render_template('document/catalog.html') + return render_template('document/catalog.html', form=form) -@document_bp.route('/catalogs', methods=['POST']) +@document_bp.route('/catalogs', methods=['GET', 'POST']) @roles_accepted('Super User', 'Tenant Admin') def catalogs(): page = request.args.get('page', 1, type=int) @@ -108,8 +116,10 @@ def handle_catalog_selection(): catalog = Catalog.query.get_or_404(catalog_id) if action == 'set_session_catalog': + current_app.logger.info(f'Setting session catalog to {catalog.name}') session['catalog_id'] = catalog_id session['catalog_name'] = catalog.name + current_app.logger.info(f'Finished setting session catalog to {catalog.name}') elif action == 'edit_catalog': return redirect(prefixed_url_for('document_bp.edit_catalog', catalog_id=catalog_id)) @@ -125,6 +135,16 @@ def edit_catalog(catalog_id): if request.method == 'POST' and form.validate_on_submit(): form.populate_obj(catalog) + # Handle Embedding Variables + catalog.html_tags = [tag.strip() for tag in form.html_tags.data.split(',')] if form.html_tags.data else [] + catalog.html_end_tags = [tag.strip() for tag in form.html_end_tags.data.split(',')] \ + if form.html_end_tags.data else [] + catalog.html_included_elements = [tag.strip() for tag in form.html_included_elements.data.split(',')] \ + if form.html_included_elements.data else [] + catalog.html_excluded_elements = [tag.strip() for tag in form.html_excluded_elements.data.split(',')] \ + if form.html_excluded_elements.data else [] + catalog.html_excluded_classes = [cls.strip() for cls in form.html_excluded_classes.data.split(',')] \ + if form.html_excluded_classes.data else [] update_logging_information(catalog, dt.now(tz.utc)) try: db.session.add(catalog) diff --git a/eveai_app/views/user_views.py b/eveai_app/views/user_views.py index 384e745..16b97ea 100644 --- a/eveai_app/views/user_views.py +++ b/eveai_app/views/user_views.py @@ -266,10 +266,16 @@ def handle_tenant_selection(): tenant_identification = request.form['selected_row'] tenant_id = ast.literal_eval(tenant_identification).get('value') the_tenant = Tenant.query.get(tenant_id) + + # set tenant information in the session session['tenant'] = the_tenant.to_dict() session['default_language'] = the_tenant.default_language session['embedding_model'] = the_tenant.embedding_model session['llm_model'] = the_tenant.llm_model + # remove catalog-related items from the session + session.pop('catalog_id', None) + session.pop('catalog_name', None) + action = request.form['action'] match action: diff --git a/eveai_chat_workers/tasks.py b/eveai_chat_workers/tasks.py index 89135f7..4733658 100644 --- a/eveai_chat_workers/tasks.py +++ b/eveai_chat_workers/tasks.py @@ -36,7 +36,7 @@ def ping(): def detail_question(question, language, model_variables, session_id): current_app.logger.debug(f'Detail question: {question}') - current_app.logger.debug(f'model_varialbes: {model_variables}') + current_app.logger.debug(f'model_variables: {model_variables}') current_app.logger.debug(f'session_id: {session_id}') retriever = EveAIHistoryRetriever(model_variables=model_variables, session_id=session_id) llm = model_variables['llm'] diff --git a/eveai_workers/tasks.py b/eveai_workers/tasks.py index c6736b6..50ad4be 100644 --- a/eveai_workers/tasks.py +++ b/eveai_workers/tasks.py @@ -13,7 +13,7 @@ from langchain_core.runnables import RunnablePassthrough from sqlalchemy.exc import SQLAlchemyError from common.extensions import db, minio_client -from common.models.document import DocumentVersion, Embedding +from common.models.document import DocumentVersion, Embedding, Document from common.models.user import Tenant from common.utils.celery_utils import current_celery from common.utils.database import Database @@ -50,8 +50,12 @@ def create_embeddings(tenant_id, document_version_id): if document_version is None: raise Exception(f'Document version {document_version_id} not found') + # Retrieve the Catalog ID + doc = Document.query.get_or_404(document_version.doc_id) + catalog_id = doc.catalog_id + # Select variables to work with depending on tenant and model - model_variables = select_model_variables(tenant) + model_variables = select_model_variables(tenant, catalog_id=catalog_id) current_app.logger.debug(f'Model variables: {model_variables}') except Exception as e: diff --git a/migrations/tenant/env.py b/migrations/tenant/env.py index e239846..d223524 100644 --- a/migrations/tenant/env.py +++ b/migrations/tenant/env.py @@ -1,5 +1,7 @@ import inspect import logging +import sys +import os from logging.config import fileConfig from flask import current_app @@ -19,8 +21,26 @@ config = context.config # Interpret the config file for Python logging. # This line sets up loggers basically. -fileConfig(config.config_file_name) -logger = logging.getLogger('alembic.env') +# fileConfig(config.config_file_name) +# logger = logging.getLogger('alembic.env') + +logging.basicConfig( + stream=sys.stdout, + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) + +logger = logging.getLogger() + +# Reset handlers to avoid issues with Alembic overriding them +for handler in logger.handlers: + logger.removeHandler(handler) + +# Add a stream handler to output logs to the console +console_handler = logging.StreamHandler(sys.stdout) +console_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) +logger.addHandler(console_handler) +logger.setLevel(logging.INFO) def get_engine(): @@ -125,6 +145,7 @@ def run_migrations_online(): tenants = get_tenant_ids() for tenant in tenants: try: + os.environ['TENANT_ID'] = str(tenant) logger.info(f"Migrating tenant: {tenant}") # set search path on the connection, which ensures that # PostgreSQL will emit all CREATE / ALTER / DROP statements diff --git a/migrations/tenant/versions/0f5932ff3051_adding_catalogs_to_document_domain.py b/migrations/tenant/versions/0f5932ff3051_adding_catalogs_to_document_domain.py new file mode 100644 index 0000000..fdb3dc9 --- /dev/null +++ b/migrations/tenant/versions/0f5932ff3051_adding_catalogs_to_document_domain.py @@ -0,0 +1,56 @@ +"""Adding Catalogs to Document Domain + +Revision ID: 0f5932ff3051 +Revises: 5a75fb6da7b8 +Create Date: 2024-10-14 15:20:45.058329 + +""" +from alembic import op +import sqlalchemy as sa +import pgvector +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '0f5932ff3051' +down_revision = '5a75fb6da7b8' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('catalog', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=50), nullable=False), + sa.Column('description', sa.Text(), nullable=True), + sa.Column('html_tags', postgresql.ARRAY(sa.String(length=10)), nullable=True), + sa.Column('html_end_tags', postgresql.ARRAY(sa.String(length=10)), nullable=True), + sa.Column('html_included_elements', postgresql.ARRAY(sa.String(length=50)), nullable=True), + sa.Column('html_excluded_elements', postgresql.ARRAY(sa.String(length=50)), nullable=True), + sa.Column('html_excluded_classes', postgresql.ARRAY(sa.String(length=200)), nullable=True), + sa.Column('min_chunk_size', sa.Integer(), nullable=True), + sa.Column('max_chunk_size', sa.Integer(), nullable=True), + sa.Column('es_k', sa.Integer(), nullable=True), + sa.Column('es_similarity_threshold', sa.Float(), nullable=True), + sa.Column('chat_RAG_temperature', sa.Float(), nullable=True), + sa.Column('chat_no_RAG_temperature', sa.Float(), nullable=True), + sa.Column('embed_tuning', sa.Boolean(), nullable=True), + sa.Column('rag_tuning', sa.Boolean(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), + sa.Column('created_by', sa.Integer(), nullable=True), + sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), + sa.Column('updated_by', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['created_by'], ['public.user.id'], ), + sa.ForeignKeyConstraint(['updated_by'], ['public.user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.add_column('document', sa.Column('catalog_id', sa.Integer(), nullable=True)) + op.create_foreign_key(None, 'document', 'catalog', ['catalog_id'], ['id']) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('document', 'catalog_id') + op.drop_table('catalog') + # ### end Alembic commands ### diff --git a/migrations/tenant/versions/28984b05d396_upgrading_existing_documents_to_default_.py b/migrations/tenant/versions/28984b05d396_upgrading_existing_documents_to_default_.py new file mode 100644 index 0000000..526217f --- /dev/null +++ b/migrations/tenant/versions/28984b05d396_upgrading_existing_documents_to_default_.py @@ -0,0 +1,99 @@ +"""Upgrading Existing documents to default catalog + +Revision ID: 28984b05d396 +Revises: 0f5932ff3051 +Create Date: 2024-10-15 09:02:23.355660 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.orm import Session +import pgvector +from common.models.document import Catalog, Document +from common.models.user import Tenant +from flask import current_app +import logging +import os + +# Set up logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# Create a console handler +console_handler = logging.StreamHandler() +console_handler.setLevel(logging.INFO) + +# Create a logging format +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +console_handler.setFormatter(formatter) + +# Add the handler to the logger +logger.addHandler(console_handler) + +logger.info("Starting revision upgrade 28984b05d396") + +# revision identifiers, used by Alembic. +revision = '28984b05d396' +down_revision = '0f5932ff3051' +branch_labels = None +depends_on = None + + +def upgrade(): + logger.info("Starting migration: Creating default catalog and updating documents.") + + bind = op.get_bind() + session = Session(bind=bind) + + try: + tenant_id = int(os.getenv('TENANT_ID')) + logger.info(f"In migration: tenant_id = {tenant_id}") + + # Step 1: Create a new Default Catalog + logger.info("Creating default catalog") + default_catalog = Catalog( + name='Default Catalog', + description=None, + ) + tenant = Tenant.query.get_or_404(tenant_id) + default_catalog.html_tags = tenant.html_tags + default_catalog.html_end_tags = tenant.html_end_tags + default_catalog.html_included_elements = tenant.html_included_elements + default_catalog.html_excluded_elements = tenant.html_excluded_elements + default_catalog.html_excluded_classes = tenant.html_excluded_classes + default_catalog.min_chunk_size = tenant.min_chunk_size + default_catalog.max_chunk_size = tenant.max_chunk_size + default_catalog.es_k = tenant.es_k + default_catalog.es_similarity_threshold = tenant.es_similarity_threshold + default_catalog.chat_RAG_temperature = tenant.chat_RAG_temperature + default_catalog.chat_no_RAG_temperature = tenant.chat_no_RAG_temperature + default_catalog.embed_tuning = tenant.embed_tuning + default_catalog.rag_tuning = tenant.rag_tuning + + session.add(default_catalog) + session.commit() + + new_catalog_id = default_catalog.id + logger.info(f"Default catalog created with ID: {new_catalog_id}") + + # Step 2: Update all documents to use this new catalog + logger.info("Updating documents with the new catalog ID.") + documents = session.query(Document).all() + for document in documents: + document.catalog_id = new_catalog_id + session.commit() + + logger.info(f"Updated {len(documents)} documents with new catalog ID.") + + except Exception as e: + logger.error(f"An error occurred during migration: {e}") + session.rollback() + raise + finally: + session.close() + + logger.info("Migration completed successfully.") + + +def downgrade(): + pass diff --git a/nginx/public/chat_evie.html b/nginx/public/chat_evie.html index 9d957f7..d41af6f 100644 --- a/nginx/public/chat_evie.html +++ b/nginx/public/chat_evie.html @@ -17,7 +17,7 @@ document.addEventListener('DOMContentLoaded', function() { const eveAI = new EveAI( '2', - 'EveAI-CHAT-9079-8604-7441-6496-7604', + 'EveAI-CHAT-6525-5692-6412-5828-7546', 'http://macstudio.ask-eve-ai-local.com', 'en', 'en,fr,nl',