| click.echo( | click.echo( | ||||
| click.style(f'Congratulations! add annotation question value successful. Deal count {message_annotation_deal_count}', fg='green')) | click.style(f'Congratulations! add annotation question value successful. Deal count {message_annotation_deal_count}', fg='green')) | ||||
| @click.command('migrate-universal-chat-to-installed-app', help='Migrate universal chat to installed app.') | |||||
| @click.option("--batch-size", default=500, help="Number of records to migrate in each batch.") | |||||
| def migrate_universal_chat_to_installed_app(batch_size): | |||||
| total_records = db.session.query(App).filter( | |||||
| App.is_universal == True | |||||
| ).count() | |||||
| if total_records == 0: | |||||
| click.secho("No data to migrate.", fg='green') | |||||
| return | |||||
| num_batches = (total_records + batch_size - 1) // batch_size | |||||
| with tqdm(total=total_records, desc="Migrating Data") as pbar: | |||||
| for i in range(num_batches): | |||||
| offset = i * batch_size | |||||
| limit = min(batch_size, total_records - offset) | |||||
| click.secho(f"Fetching batch {i + 1}/{num_batches} from source database...", fg='green') | |||||
| data_batch: list[App] = db.session.query(App) \ | |||||
| .filter(App.is_universal == True) \ | |||||
| .order_by(App.created_at) \ | |||||
| .offset(offset).limit(limit).all() | |||||
| if not data_batch: | |||||
| click.secho("No more data to migrate.", fg='green') | |||||
| break | |||||
| try: | |||||
| click.secho(f"Migrating {len(data_batch)} records...", fg='green') | |||||
| for data in data_batch: | |||||
| # check if the app is already installed | |||||
| installed_app = db.session.query(InstalledApp).filter( | |||||
| InstalledApp.app_id == data.id | |||||
| ).first() | |||||
| if installed_app: | |||||
| continue | |||||
| # insert installed app | |||||
| installed_app = InstalledApp( | |||||
| app_id=data.id, | |||||
| tenant_id=data.tenant_id, | |||||
| position=0, | |||||
| app_owner_tenant_id=data.tenant_id, | |||||
| is_pinned=True, | |||||
| last_used_at=datetime.datetime.utcnow(), | |||||
| ) | |||||
| db.session.add(installed_app) | |||||
| db.session.commit() | |||||
| except Exception as e: | |||||
| click.secho(f"Error while migrating data: {e}, app_id: {data.id}", fg='red') | |||||
| continue | |||||
| click.secho(f"Successfully migrated batch {i + 1}/{num_batches}.", fg='green') | |||||
| pbar.update(len(data_batch)) | |||||
| def register_commands(app): | def register_commands(app): | ||||
| app.cli.add_command(reset_password) | app.cli.add_command(reset_password) | ||||
| app.cli.add_command(migrate_default_input_to_dataset_query_variable) | app.cli.add_command(migrate_default_input_to_dataset_query_variable) | ||||
| app.cli.add_command(add_qdrant_full_text_index) | app.cli.add_command(add_qdrant_full_text_index) | ||||
| app.cli.add_command(add_annotation_question_field_value) | app.cli.add_command(add_annotation_question_field_value) | ||||
| app.cli.add_command(migrate_universal_chat_to_installed_app) |
| filters = [ | filters = [ | ||||
| App.tenant_id == current_user.current_tenant_id, | App.tenant_id == current_user.current_tenant_id, | ||||
| App.is_universal == False | |||||
| ] | ] | ||||
| if args['mode'] == 'completion': | if args['mode'] == 'completion': |
| # -*- coding:utf-8 -*- | |||||
| import logging | |||||
| import services | |||||
| from controllers.console import api | |||||
| from controllers.console.app.error import (AppUnavailableError, AudioTooLargeError, CompletionRequestError, | |||||
| NoAudioUploadedError, ProviderModelCurrentlyNotSupportError, | |||||
| ProviderNotInitializeError, ProviderNotSupportSpeechToTextError, | |||||
| ProviderQuotaExceededError, UnsupportedAudioTypeError) | |||||
| from controllers.console.universal_chat.wraps import UniversalChatResource | |||||
| from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError | |||||
| from core.model_runtime.errors.invoke import InvokeError | |||||
| from flask import request | |||||
| from models.model import AppModelConfig | |||||
| from services.audio_service import AudioService | |||||
| from services.errors.audio import (AudioTooLargeServiceError, NoAudioUploadedServiceError, | |||||
| ProviderNotSupportSpeechToTextServiceError, UnsupportedAudioTypeServiceError) | |||||
| from werkzeug.exceptions import InternalServerError | |||||
| class UniversalChatAudioApi(UniversalChatResource): | |||||
| def post(self, universal_app): | |||||
| app_model = universal_app | |||||
| app_model_config: AppModelConfig = app_model.app_model_config | |||||
| if not app_model_config.speech_to_text_dict['enabled']: | |||||
| raise AppUnavailableError() | |||||
| file = request.files['file'] | |||||
| try: | |||||
| response = AudioService.transcript( | |||||
| tenant_id=app_model.tenant_id, | |||||
| file=file, | |||||
| ) | |||||
| return response | |||||
| except services.errors.app_model_config.AppModelConfigBrokenError: | |||||
| logging.exception("App model config broken.") | |||||
| raise AppUnavailableError() | |||||
| except NoAudioUploadedServiceError: | |||||
| raise NoAudioUploadedError() | |||||
| except AudioTooLargeServiceError as e: | |||||
| raise AudioTooLargeError(str(e)) | |||||
| except UnsupportedAudioTypeServiceError: | |||||
| raise UnsupportedAudioTypeError() | |||||
| except ProviderNotSupportSpeechToTextServiceError: | |||||
| raise ProviderNotSupportSpeechToTextError() | |||||
| except ProviderTokenNotInitError: | |||||
| raise ProviderNotInitializeError() | |||||
| except QuotaExceededError: | |||||
| raise ProviderQuotaExceededError() | |||||
| except ModelCurrentlyNotSupportError: | |||||
| raise ProviderModelCurrentlyNotSupportError() | |||||
| except InvokeError as e: | |||||
| raise CompletionRequestError(e.description) | |||||
| except ValueError as e: | |||||
| raise e | |||||
| except Exception as e: | |||||
| logging.exception("internal server error.") | |||||
| raise InternalServerError() | |||||