mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-25 17:22:55 +00:00
feat: i18n (#2011)
This commit is contained in:
parent
41c7ed90c1
commit
a28de6feaf
|
|
@ -15,7 +15,6 @@ import re
|
|||
import uuid
|
||||
from functools import reduce
|
||||
from typing import Dict, List
|
||||
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from django.core import cache, validators
|
||||
from django.core import signing
|
||||
|
|
@ -54,8 +53,7 @@ from setting.models_provider.tools import get_model_instance_by_model_user_id
|
|||
from setting.serializers.provider_serializers import ModelSerializer
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from users.models import User
|
||||
from django.db.models import Value
|
||||
from django.db.models.fields.json import KeyTextTransform
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
chat_cache = cache.caches['chat_cache']
|
||||
|
||||
|
|
@ -194,10 +192,11 @@ def get_base_node_work_flow(work_flow):
|
|||
|
||||
|
||||
class ApplicationSerializer(serializers.Serializer):
|
||||
name = serializers.CharField(required=True, max_length=64, min_length=1, error_messages=ErrMessage.char("应用名称"))
|
||||
name = serializers.CharField(required=True, max_length=64, min_length=1,
|
||||
error_messages=ErrMessage.char(_("application name")))
|
||||
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True,
|
||||
max_length=256, min_length=1,
|
||||
error_messages=ErrMessage.char("应用描述"))
|
||||
error_messages=ErrMessage.char(_("application describe")))
|
||||
model_id = serializers.CharField(required=False, allow_null=True, allow_blank=True,
|
||||
error_messages=ErrMessage.char("模型"))
|
||||
dialogue_number = serializers.IntegerField(required=True,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from rest_framework.authentication import TokenAuthentication
|
|||
|
||||
from common.exception.app_exception import AppAuthenticationFailed, AppEmbedIdentityFailed, AppChatNumOutOfBoundsFailed, \
|
||||
ChatException, AppApiException
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
token_cache = cache.caches['token_cache']
|
||||
|
||||
|
||||
|
|
@ -59,19 +59,19 @@ class OpenAIKeyAuth(TokenAuthentication):
|
|||
auth = auth.replace('Bearer ', '')
|
||||
# 未认证
|
||||
if auth is None:
|
||||
raise AppAuthenticationFailed(1003, '未登录,请先登录')
|
||||
raise AppAuthenticationFailed(1003, _('Not logged in, please log in first'))
|
||||
try:
|
||||
token_details = TokenDetails(auth)
|
||||
for handle in handles:
|
||||
if handle.support(request, auth, token_details.get_token_details):
|
||||
return handle.handle(request, auth, token_details.get_token_details)
|
||||
raise AppAuthenticationFailed(1002, "身份验证信息不正确!非法用户")
|
||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect! illegal user'))
|
||||
except Exception as e:
|
||||
traceback.format_exc()
|
||||
if isinstance(e, AppEmbedIdentityFailed) or isinstance(e, AppChatNumOutOfBoundsFailed) or isinstance(e,
|
||||
AppApiException):
|
||||
raise e
|
||||
raise AppAuthenticationFailed(1002, "身份验证信息不正确!非法用户")
|
||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect! illegal user'))
|
||||
|
||||
|
||||
class TokenAuth(TokenAuthentication):
|
||||
|
|
@ -80,16 +80,16 @@ class TokenAuth(TokenAuthentication):
|
|||
auth = request.META.get('HTTP_AUTHORIZATION')
|
||||
# 未认证
|
||||
if auth is None:
|
||||
raise AppAuthenticationFailed(1003, '未登录,请先登录')
|
||||
raise AppAuthenticationFailed(1003, _('Not logged in, please log in first'))
|
||||
try:
|
||||
token_details = TokenDetails(auth)
|
||||
for handle in handles:
|
||||
if handle.support(request, auth, token_details.get_token_details):
|
||||
return handle.handle(request, auth, token_details.get_token_details)
|
||||
raise AppAuthenticationFailed(1002, "身份验证信息不正确!非法用户")
|
||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect! illegal user'))
|
||||
except Exception as e:
|
||||
traceback.format_exc()
|
||||
if isinstance(e, AppEmbedIdentityFailed) or isinstance(e, AppChatNumOutOfBoundsFailed) or isinstance(e,
|
||||
AppApiException):
|
||||
raise e
|
||||
raise AppAuthenticationFailed(1002, "身份验证信息不正确!非法用户")
|
||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect! illegal user'))
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from typing import List
|
|||
from common.constants.permission_constants import ViewPermission, CompareConstants, RoleConstants, PermissionConstants, \
|
||||
Permission
|
||||
from common.exception.app_exception import AppUnauthorizedFailed
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
def exist_permissions_by_permission_constants(user_permission: List[PermissionConstants],
|
||||
permission_list: List[PermissionConstants]):
|
||||
|
|
@ -91,7 +91,7 @@ def has_permissions(*permission, compare=CompareConstants.OR):
|
|||
# 判断是否有权限
|
||||
if any(exit_list) if compare == CompareConstants.OR else all(exit_list):
|
||||
return func(view, request, **kwargs)
|
||||
raise AppUnauthorizedFailed(403, "没有权限访问")
|
||||
raise AppUnauthorizedFailed(403, _('No permission to access'))
|
||||
|
||||
return run
|
||||
|
||||
|
|
|
|||
|
|
@ -13,15 +13,16 @@ from common.auth.handle.auth_base_handle import AuthBaseHandle
|
|||
from common.constants.authentication_type import AuthenticationType
|
||||
from common.constants.permission_constants import Permission, Group, Operate, RoleConstants, Auth
|
||||
from common.exception.app_exception import AppAuthenticationFailed
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class ApplicationKey(AuthBaseHandle):
|
||||
def handle(self, request, token: str, get_token_details):
|
||||
application_api_key = QuerySet(ApplicationApiKey).filter(secret_key=token).first()
|
||||
if application_api_key is None:
|
||||
raise AppAuthenticationFailed(500, "secret_key 无效")
|
||||
raise AppAuthenticationFailed(500, _('Secret key is invalid'))
|
||||
if not application_api_key.is_active:
|
||||
raise AppAuthenticationFailed(500, "secret_key 无效")
|
||||
raise AppAuthenticationFailed(500, _('Secret key is invalid'))
|
||||
permission_list = [Permission(group=Group.APPLICATION,
|
||||
operate=Operate.USE,
|
||||
dynamic_tag=str(
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from common.constants.permission_constants import RoleConstants, Permission, Gro
|
|||
from common.exception.app_exception import AppAuthenticationFailed, ChatException
|
||||
from common.models.db_model_manage import DBModelManage
|
||||
from common.util.common import password_encrypt
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class PublicAccessToken(AuthBaseHandle):
|
||||
def support(self, request, token: str, get_token_details):
|
||||
|
|
@ -45,13 +45,13 @@ class PublicAccessToken(AuthBaseHandle):
|
|||
if application_setting.authentication_value.get('type') != authentication.get(
|
||||
'type') or password_encrypt(
|
||||
application_setting.authentication_value.get('value')) != authentication.get('value'):
|
||||
raise ChatException(1002, "身份验证信息不正确")
|
||||
raise ChatException(1002, _('Authentication information is incorrect'))
|
||||
if application_access_token is None:
|
||||
raise AppAuthenticationFailed(1002, "身份验证信息不正确")
|
||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
||||
if not application_access_token.is_active:
|
||||
raise AppAuthenticationFailed(1002, "身份验证信息不正确")
|
||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
||||
if not application_access_token.access_token == auth_details.get('access_token'):
|
||||
raise AppAuthenticationFailed(1002, "身份验证信息不正确")
|
||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
||||
|
||||
return application_access_token.application.user, Auth(
|
||||
role_list=[RoleConstants.APPLICATION_ACCESS_TOKEN],
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from users.models import User
|
|||
from django.core import cache
|
||||
|
||||
from users.models.user import get_user_dynamics_permission
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
token_cache = cache.caches['token_cache']
|
||||
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ class UserToken(AuthBaseHandle):
|
|||
def handle(self, request, token: str, get_token_details):
|
||||
cache_token = token_cache.get(token)
|
||||
if cache_token is None:
|
||||
raise AppAuthenticationFailed(1002, "登录过期")
|
||||
raise AppAuthenticationFailed(1002, _('Login expired'))
|
||||
auth_details = get_token_details()
|
||||
user = QuerySet(User).get(id=auth_details['id'])
|
||||
# 续期
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
from enum import Enum
|
||||
|
||||
from common.exception.app_exception import AppApiException
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class ExceptionCodeConstantsValue:
|
||||
|
|
@ -27,13 +28,16 @@ class ExceptionCodeConstantsValue:
|
|||
|
||||
|
||||
class ExceptionCodeConstants(Enum):
|
||||
INCORRECT_USERNAME_AND_PASSWORD = ExceptionCodeConstantsValue(1000, "用户名或者密码不正确")
|
||||
NOT_AUTHENTICATION = ExceptionCodeConstantsValue(1001, "请先登录,并携带用户Token")
|
||||
EMAIL_SEND_ERROR = ExceptionCodeConstantsValue(1002, "邮件发送失败")
|
||||
EMAIL_FORMAT_ERROR = ExceptionCodeConstantsValue(1003, "邮箱格式错误")
|
||||
EMAIL_IS_EXIST = ExceptionCodeConstantsValue(1004, "邮箱已经被注册,请勿重复注册")
|
||||
EMAIL_IS_NOT_EXIST = ExceptionCodeConstantsValue(1005, "邮箱尚未注册,请先注册")
|
||||
CODE_ERROR = ExceptionCodeConstantsValue(1005, "验证码不正确,或者验证码过期")
|
||||
USERNAME_IS_EXIST = ExceptionCodeConstantsValue(1006, "用户名已被使用,请使用其他用户名")
|
||||
USERNAME_ERROR = ExceptionCodeConstantsValue(1006, "用户名不能为空,并且长度在6-20")
|
||||
PASSWORD_NOT_EQ_RE_PASSWORD = ExceptionCodeConstantsValue(1007, "密码与确认密码不一致")
|
||||
INCORRECT_USERNAME_AND_PASSWORD = ExceptionCodeConstantsValue(1000, _('The username or password is incorrect'))
|
||||
NOT_AUTHENTICATION = ExceptionCodeConstantsValue(1001, _('Please log in first and bring the user Token'))
|
||||
EMAIL_SEND_ERROR = ExceptionCodeConstantsValue(1002, _('Email sending failed'))
|
||||
EMAIL_FORMAT_ERROR = ExceptionCodeConstantsValue(1003, _('Email format error'))
|
||||
EMAIL_IS_EXIST = ExceptionCodeConstantsValue(1004, _('The email has been registered, please log in directly'))
|
||||
EMAIL_IS_NOT_EXIST = ExceptionCodeConstantsValue(1005, _('The email is not registered, please register first'))
|
||||
CODE_ERROR = ExceptionCodeConstantsValue(1005,
|
||||
_('The verification code is incorrect or the verification code has expired'))
|
||||
USERNAME_IS_EXIST = ExceptionCodeConstantsValue(1006, _('The username has been registered, please log in directly'))
|
||||
USERNAME_ERROR = ExceptionCodeConstantsValue(1006,
|
||||
_('The username cannot be empty and must be between 6 and 20 characters long.'))
|
||||
PASSWORD_NOT_EQ_RE_PASSWORD = ExceptionCodeConstantsValue(1007,
|
||||
_('Password and confirmation password are inconsistent'))
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
"""
|
||||
from enum import Enum
|
||||
from typing import List
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class Group(Enum):
|
||||
"""
|
||||
|
|
@ -58,10 +58,10 @@ class Role:
|
|||
|
||||
|
||||
class RoleConstants(Enum):
|
||||
ADMIN = Role("管理员", "管理员,预制目前不会使用", RoleGroup.USER)
|
||||
USER = Role("用户", "用户所有权限", RoleGroup.USER)
|
||||
APPLICATION_ACCESS_TOKEN = Role("会话", "只拥有应用会话框接口权限", RoleGroup.APPLICATION_ACCESS_TOKEN),
|
||||
APPLICATION_KEY = Role("应用私钥", "应用私钥", RoleGroup.APPLICATION_KEY)
|
||||
ADMIN = Role(_("ADMIN"), _('Admin, prefabs are not currently used'), RoleGroup.USER)
|
||||
USER = Role(_("USER"), _('All user permissions'), RoleGroup.USER)
|
||||
APPLICATION_ACCESS_TOKEN = Role(_('chat'), _('Only has application dialog interface permissions'), RoleGroup.APPLICATION_ACCESS_TOKEN),
|
||||
APPLICATION_KEY = Role(_('Apply private key'), _('Apply private key'), RoleGroup.APPLICATION_KEY)
|
||||
|
||||
|
||||
class Permission:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@
|
|||
import setting.models
|
||||
from setting.models import Model
|
||||
from .listener_manage import *
|
||||
from common.db.sql_execute import update_execute
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from ..db.sql_execute import update_execute
|
||||
|
||||
update_document_status_sql = """
|
||||
UPDATE "public"."document"
|
||||
|
|
@ -20,5 +22,5 @@ SET status ="replace"("replace"("replace"(status, '1', '3'), '0', '3'), '4', '3'
|
|||
def run():
|
||||
# QuerySet(Document).filter(status__in=[Status.embedding, Status.queue_up]).update(**{'status': Status.error})
|
||||
QuerySet(Model).filter(status=setting.models.Status.DOWNLOAD).update(status=setting.models.Status.ERROR,
|
||||
meta={'message': "下载程序被中断,请重试"})
|
||||
meta={'message': _('The download process was interrupted, please try again')})
|
||||
update_execute(update_document_status_sql, [])
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ from common.util.page_utils import page_desc
|
|||
from dataset.models import Paragraph, Status, Document, ProblemParagraphMapping, TaskType, State
|
||||
from embedding.models import SourceType, SearchMode
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
max_kb_error = logging.getLogger(__file__)
|
||||
max_kb = logging.getLogger(__file__)
|
||||
|
|
@ -86,11 +87,12 @@ class ListenerManagement:
|
|||
ListenerManagement.embedding_by_paragraph_data_list(data_list, paragraph_id_list=paragraph_id_list,
|
||||
embedding_model=embedding_model)
|
||||
except Exception as e:
|
||||
max_kb_error.error(f'查询向量数据:{paragraph_id_list}出现错误{str(e)}{traceback.format_exc()}')
|
||||
max_kb_error.error(_('Query vector data: {paragraph_id_list} error {error} {traceback}').format(
|
||||
paragraph_id_list=paragraph_id_list, error=str(e), traceback=traceback.format_exc()))
|
||||
|
||||
@staticmethod
|
||||
def embedding_by_paragraph_data_list(data_list, paragraph_id_list, embedding_model: Embeddings):
|
||||
max_kb.info(f'开始--->向量化段落:{paragraph_id_list}')
|
||||
max_kb.info(_('Start--->Embedding paragraph: {paragraph_id_list}').format(paragraph_id_list=paragraph_id_list))
|
||||
status = Status.success
|
||||
try:
|
||||
# 删除段落
|
||||
|
|
@ -102,11 +104,13 @@ class ListenerManagement:
|
|||
# 批量向量化
|
||||
VectorStore.get_embedding_vector().batch_save(data_list, embedding_model, is_save_function)
|
||||
except Exception as e:
|
||||
max_kb_error.error(f'向量化段落:{paragraph_id_list}出现错误{str(e)}{traceback.format_exc()}')
|
||||
max_kb_error.error(_('Vectorized paragraph: {paragraph_id_list} error {error} {traceback}').format(
|
||||
paragraph_id_list=paragraph_id_list, error=str(e), traceback=traceback.format_exc()))
|
||||
status = Status.error
|
||||
finally:
|
||||
QuerySet(Paragraph).filter(id__in=paragraph_id_list).update(**{'status': status})
|
||||
max_kb.info(f'结束--->向量化段落:{paragraph_id_list}')
|
||||
max_kb.info(
|
||||
_('End--->Embedding paragraph: {paragraph_id_list}').format(paragraph_id_list=paragraph_id_list))
|
||||
|
||||
@staticmethod
|
||||
def embedding_by_paragraph(paragraph_id, embedding_model: Embeddings):
|
||||
|
|
@ -115,7 +119,7 @@ class ListenerManagement:
|
|||
@param paragraph_id: 段落id
|
||||
@param embedding_model: 向量模型
|
||||
"""
|
||||
max_kb.info(f"开始--->向量化段落:{paragraph_id}")
|
||||
max_kb.info(_('Start--->Embedding paragraph: {paragraph_id}').format(paragraph_id=paragraph_id))
|
||||
# 更新到开始状态
|
||||
ListenerManagement.update_status(QuerySet(Paragraph).filter(id=paragraph_id), TaskType.EMBEDDING, State.STARTED)
|
||||
try:
|
||||
|
|
@ -140,11 +144,12 @@ class ListenerManagement:
|
|||
ListenerManagement.update_status(QuerySet(Paragraph).filter(id=paragraph_id), TaskType.EMBEDDING,
|
||||
State.SUCCESS)
|
||||
except Exception as e:
|
||||
max_kb_error.error(f'向量化段落:{paragraph_id}出现错误{str(e)}{traceback.format_exc()}')
|
||||
max_kb_error.error(_('Vectorized paragraph: {paragraph_id} error {error} {traceback}').format(
|
||||
paragraph_id=paragraph_id, error=str(e), traceback=traceback.format_exc()))
|
||||
ListenerManagement.update_status(QuerySet(Paragraph).filter(id=paragraph_id), TaskType.EMBEDDING,
|
||||
State.FAILURE)
|
||||
finally:
|
||||
max_kb.info(f'结束--->向量化段落:{paragraph_id}')
|
||||
max_kb.info(_('End--->Embedding paragraph: {paragraph_id}').format(paragraph_id=paragraph_id))
|
||||
|
||||
@staticmethod
|
||||
def embedding_by_data_list(data_list: List, embedding_model: Embeddings):
|
||||
|
|
@ -258,7 +263,8 @@ class ListenerManagement:
|
|||
|
||||
if is_the_task_interrupted():
|
||||
return
|
||||
max_kb.info(f"开始--->向量化文档:{document_id}")
|
||||
max_kb.info(_('Start--->Embedding document: {document_id}').format(document_id=document_id)
|
||||
)
|
||||
# 批量修改状态为PADDING
|
||||
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id), TaskType.EMBEDDING,
|
||||
State.STARTED)
|
||||
|
|
@ -279,11 +285,12 @@ class ListenerManagement:
|
|||
document_id)),
|
||||
is_the_task_interrupted)
|
||||
except Exception as e:
|
||||
max_kb_error.error(f'向量化文档:{document_id}出现错误{str(e)}{traceback.format_exc()}')
|
||||
max_kb_error.error(_('Vectorized document: {document_id} error {error} {traceback}').format(
|
||||
document_id=document_id, error=str(e), traceback=traceback.format_exc()))
|
||||
finally:
|
||||
ListenerManagement.post_update_document_status(document_id, TaskType.EMBEDDING)
|
||||
ListenerManagement.get_aggregation_document_status(document_id)()
|
||||
max_kb.info(f"结束--->向量化文档:{document_id}")
|
||||
max_kb.info(_('End--->Embedding document: {document_id}').format(document_id=document_id))
|
||||
un_lock('embedding' + str(document_id))
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -294,17 +301,18 @@ class ListenerManagement:
|
|||
@param embedding_model 向量模型
|
||||
:return: None
|
||||
"""
|
||||
max_kb.info(f"开始--->向量化数据集:{dataset_id}")
|
||||
max_kb.info(_('Start--->Embedding dataset: {dataset_id}').format(dataset_id=dataset_id))
|
||||
try:
|
||||
ListenerManagement.delete_embedding_by_dataset(dataset_id)
|
||||
document_list = QuerySet(Document).filter(dataset_id=dataset_id)
|
||||
max_kb.info(f"数据集文档:{[d.name for d in document_list]}")
|
||||
max_kb.info(_('Start--->Embedding document: {document_list}').format(document_list=document_list))
|
||||
for document in document_list:
|
||||
ListenerManagement.embedding_by_document(document.id, embedding_model=embedding_model)
|
||||
except Exception as e:
|
||||
max_kb_error.error(f'向量化数据集:{dataset_id}出现错误{str(e)}{traceback.format_exc()}')
|
||||
max_kb_error.error(_('Vectorized dataset: {dataset_id} error {error} {traceback}').format(
|
||||
dataset_id=dataset_id, error=str(e), traceback=traceback.format_exc()))
|
||||
finally:
|
||||
max_kb.info(f"结束--->向量化数据集:{dataset_id}")
|
||||
max_kb.info(_('End--->Embedding dataset: {dataset_id}').format(dataset_id=dataset_id))
|
||||
|
||||
@staticmethod
|
||||
def delete_embedding_by_document(document_id):
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
@desc:
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class ObjectField(serializers.Field):
|
||||
def __init__(self, model_type_list, **kwargs):
|
||||
|
|
@ -18,7 +18,7 @@ class ObjectField(serializers.Field):
|
|||
for model_type in self.model_type_list:
|
||||
if isinstance(data, model_type):
|
||||
return data
|
||||
self.fail('message类型错误', value=data)
|
||||
self.fail(_('Message type error'), value=data)
|
||||
|
||||
def to_representation(self, value):
|
||||
return value
|
||||
|
|
@ -31,7 +31,7 @@ class InstanceField(serializers.Field):
|
|||
|
||||
def to_internal_value(self, data):
|
||||
if not isinstance(data, self.model_type):
|
||||
self.fail('message类型错误', value=data)
|
||||
self.fail(_('Message type error'), value=data)
|
||||
return data
|
||||
|
||||
def to_representation(self, value):
|
||||
|
|
@ -42,7 +42,7 @@ class FunctionField(serializers.Field):
|
|||
|
||||
def to_internal_value(self, data):
|
||||
if not callable(data):
|
||||
self.fail('不是一个函數', value=data)
|
||||
self.fail(_('not a function'), value=data)
|
||||
return data
|
||||
|
||||
def to_representation(self, value):
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from typing import List, Dict
|
|||
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.forms.label.base_label import BaseLabel
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class TriggerType(Enum):
|
||||
|
|
@ -60,7 +61,7 @@ class BaseField:
|
|||
field_label = self.label.label if hasattr(self.label, 'to_dict') else self.label
|
||||
if self.required and value is None:
|
||||
raise AppApiException(500,
|
||||
f"{field_label} 为必填参数")
|
||||
_('The field {field_label} is required').format(field_label=field_label))
|
||||
|
||||
def to_dict(self, **kwargs):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from typing import Dict
|
|||
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseField, TriggerType, BaseLabel
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class SliderField(BaseField):
|
||||
|
|
@ -52,7 +53,13 @@ class SliderField(BaseField):
|
|||
if value is not None:
|
||||
if value < self.attrs.get('min'):
|
||||
raise AppApiException(500,
|
||||
f"{field_label} 不能小于{self.attrs.get('min')}")
|
||||
_("The {field_label} cannot be less than {min}").format(field_label=field_label,
|
||||
min=self.attrs.get(
|
||||
'min')))
|
||||
|
||||
if value > self.attrs.get('max'):
|
||||
raise AppApiException(500,
|
||||
f"{field_label} 不能大于{self.attrs.get('max')}")
|
||||
_("The {field_label} cannot be greater than {max}").format(
|
||||
field_label=field_label,
|
||||
max=self.attrs.get(
|
||||
'max')))
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from rest_framework.views import exception_handler
|
|||
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.response import result
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
def to_result(key, args, parent_key=None):
|
||||
"""
|
||||
|
|
@ -27,7 +27,7 @@ def to_result(key, args, parent_key=None):
|
|||
error_detail = list(filter(
|
||||
lambda d: True if isinstance(d, ErrorDetail) else True if isinstance(d, dict) and len(
|
||||
d.keys()) > 0 else False,
|
||||
(args[0] if len(args) > 0 else {key: [ErrorDetail('未知异常', code='unknown')]}).get(key)))[0]
|
||||
(args[0] if len(args) > 0 else {key: [ErrorDetail(_('Unknown exception'), code='unknown')]}).get(key)))[0]
|
||||
|
||||
if isinstance(error_detail, dict):
|
||||
return list(map(lambda k: to_result(k, args=[error_detail],
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from docx.text.paragraph import Paragraph
|
|||
from common.handle.base_split_handle import BaseSplitHandle
|
||||
from common.util.split_model import SplitModel
|
||||
from dataset.models import Image
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
default_pattern_list = [re.compile('(?<=^)# .*|(?<=\\n)# .*'),
|
||||
re.compile('(?<=\\n)(?<!#)## (?!#).*|(?<=^)(?<!#)## (?!#).*'),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ from common.handle.impl.qa.xls_parse_qa_handle import XlsParseQAHandle
|
|||
from common.handle.impl.qa.xlsx_parse_qa_handle import XlsxParseQAHandle
|
||||
from common.util.common import parse_md_image
|
||||
from dataset.models import Image
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class FileBufferHandle:
|
||||
buffer = None
|
||||
|
|
@ -59,7 +59,7 @@ def file_to_paragraph(file):
|
|||
for split_handle in split_handles:
|
||||
if split_handle.support(file, get_buffer):
|
||||
return split_handle.handle(file, get_buffer, save_inner_image)
|
||||
raise Exception("不支持的文件格式")
|
||||
raise Exception(_("Unsupported file format"))
|
||||
|
||||
|
||||
def is_valid_uuid(uuid_str: str):
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ from common.handle.impl.xls_split_handle import XlsSplitHandle
|
|||
from common.handle.impl.xlsx_split_handle import XlsxSplitHandle
|
||||
from common.util.common import parse_md_image
|
||||
from dataset.models import Image
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class FileBufferHandle:
|
||||
buffer = None
|
||||
|
|
@ -53,7 +53,7 @@ def file_to_paragraph(file, pattern_list: List, with_filter: bool, limit: int):
|
|||
for split_handle in split_handles:
|
||||
if split_handle.support(file, get_buffer):
|
||||
return split_handle.handle(file, pattern_list, with_filter, limit, get_buffer, save_inner_image)
|
||||
raise Exception("不支持的文件格式")
|
||||
raise Exception(_('Unsupported file format'))
|
||||
|
||||
|
||||
def is_valid_uuid(uuid_str: str):
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from rest_framework import permissions
|
|||
|
||||
from common.auth import AnonymousAuthentication
|
||||
from smartdoc.const import CONFIG
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
def init_app_doc(application_urlpatterns):
|
||||
|
|
@ -22,7 +23,7 @@ def init_app_doc(application_urlpatterns):
|
|||
openapi.Info(
|
||||
title="Python API",
|
||||
default_version='v1',
|
||||
description="智能客服平台",
|
||||
description=_('Intelligent customer service platform'),
|
||||
),
|
||||
public=True,
|
||||
permission_classes=[permissions.AllowAny],
|
||||
|
|
@ -41,7 +42,7 @@ def init_chat_doc(application_urlpatterns, patterns):
|
|||
openapi.Info(
|
||||
title="Python API",
|
||||
default_version='/chat',
|
||||
description="智能客服平台",
|
||||
description=_('Intelligent customer service platform'),
|
||||
),
|
||||
public=True,
|
||||
permission_classes=[permissions.AllowAny],
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ from application.models import Application, Chat, ChatRecord
|
|||
from django.db.models import Q, Max
|
||||
from common.lock.impl.file_lock import FileLock
|
||||
from dataset.models import File
|
||||
|
||||
|
||||
from django.db import connection
|
||||
|
||||
scheduler = BackgroundScheduler()
|
||||
|
|
@ -19,7 +21,8 @@ lock = FileLock()
|
|||
|
||||
|
||||
def clean_chat_log_job():
|
||||
logging.getLogger("max_kb").info('开始清理对话记录')
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
logging.getLogger("max_kb").info(_('start clean chat log'))
|
||||
now = timezone.now()
|
||||
|
||||
applications = Application.objects.all().values('id', 'clean_time')
|
||||
|
|
@ -65,7 +68,7 @@ def clean_chat_log_job():
|
|||
if deleted_count < batch_size:
|
||||
break
|
||||
|
||||
logging.getLogger("max_kb").info(f'结束清理对话记录')
|
||||
logging.getLogger("max_kb").info(_('end clean chat log'))
|
||||
|
||||
|
||||
def run():
|
||||
|
|
@ -75,6 +78,6 @@ def run():
|
|||
existing_job = scheduler.get_job(job_id='clean_chat_log')
|
||||
if existing_job is not None:
|
||||
existing_job.remove()
|
||||
scheduler.add_job(clean_chat_log_job, 'cron', hour='0', minute='5', id='clean_chat_log')
|
||||
scheduler.add_job(clean_chat_log_job, 'cron', hour='0', minute='5', id='clean_chat_log')
|
||||
finally:
|
||||
lock.un_lock('clean_chat_log_job')
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@ lock = FileLock()
|
|||
|
||||
|
||||
def clean_debug_file():
|
||||
logging.getLogger("max_kb").info('开始清理debug文件')
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
logging.getLogger("max_kb").info(_('start clean debug file'))
|
||||
two_hours_ago = timezone.now() - timedelta(hours=2)
|
||||
# 删除对应的文件
|
||||
File.objects.filter(Q(create_time__lt=two_hours_ago) & Q(meta__debug=True)).delete()
|
||||
logging.getLogger("max_kb").info('结束清理debug文件')
|
||||
logging.getLogger("max_kb").info(_('end clean debug file'))
|
||||
|
||||
|
||||
def run():
|
||||
|
|
|
|||
|
|
@ -21,9 +21,10 @@ lock = FileLock()
|
|||
|
||||
|
||||
def client_access_num_reset_job():
|
||||
logging.getLogger("max_kb").info('开始重置access_num')
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
logging.getLogger("max_kb").info(_('start reset access_num'))
|
||||
QuerySet(ApplicationPublicAccessClient).update(intraday_access_num=0)
|
||||
logging.getLogger("max_kb").info('结束重置access_num')
|
||||
logging.getLogger("max_kb").info(_('end reset access_num'))
|
||||
|
||||
|
||||
def run():
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
@desc:
|
||||
"""
|
||||
from django.db import models
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class AppModelMixin(models.Model):
|
||||
create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
|
||||
update_time = models.DateTimeField(verbose_name="修改时间", auto_now=True)
|
||||
create_time = models.DateTimeField(verbose_name=_('Create time'), auto_now_add=True)
|
||||
update_time = models.DateTimeField(verbose_name=_('Update time'), auto_now=True)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from typing import List
|
|||
from django.http import JsonResponse
|
||||
from drf_yasg import openapi
|
||||
from rest_framework import status
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Page(dict):
|
||||
|
|
@ -20,7 +21,7 @@ class Result(JsonResponse):
|
|||
接口统一返回对象
|
||||
"""
|
||||
|
||||
def __init__(self, code=200, message="成功", data=None, response_status=status.HTTP_200_OK, **kwargs):
|
||||
def __init__(self, code=200, message=_('Success'), data=None, response_status=status.HTTP_200_OK, **kwargs):
|
||||
back_info_dict = {"code": code, "message": message, 'data': data}
|
||||
super().__init__(data=back_info_dict, status=response_status, **kwargs)
|
||||
|
||||
|
|
@ -32,13 +33,13 @@ def get_page_request_params(other_request_params=None):
|
|||
in_=openapi.IN_PATH,
|
||||
type=openapi.TYPE_INTEGER,
|
||||
required=True,
|
||||
description='当前页')
|
||||
description=_('current page'))
|
||||
|
||||
page_size = openapi.Parameter(name='page_size',
|
||||
in_=openapi.IN_PATH,
|
||||
type=openapi.TYPE_INTEGER,
|
||||
required=True,
|
||||
description='每页大小')
|
||||
description=_('page size'))
|
||||
result = [current_page, page_size]
|
||||
for other_request_param in other_request_params:
|
||||
result.append(other_request_param)
|
||||
|
|
@ -49,41 +50,41 @@ def get_page_api_response(response_data_schema: openapi.Schema):
|
|||
"""
|
||||
获取统一返回 响应Api
|
||||
"""
|
||||
return openapi.Responses(responses={200: openapi.Response(description="响应参数",
|
||||
return openapi.Responses(responses={200: openapi.Response(description=_('response parameters'),
|
||||
schema=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'code': openapi.Schema(
|
||||
type=openapi.TYPE_INTEGER,
|
||||
title="响应码",
|
||||
title=_('response code'),
|
||||
default=200,
|
||||
description="成功:200 失败:其他"),
|
||||
description=_('success:200 fail:other')),
|
||||
"message": openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="提示",
|
||||
default='成功',
|
||||
description="错误提示"),
|
||||
title=_('prompt'),
|
||||
default=_('success'),
|
||||
description=_('error prompt')),
|
||||
"data": openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'total': openapi.Schema(
|
||||
type=openapi.TYPE_INTEGER,
|
||||
title="总条数",
|
||||
title=_('total number of data'),
|
||||
default=1,
|
||||
description="数据总条数"),
|
||||
description=_('total number of data')),
|
||||
"records": openapi.Schema(
|
||||
type=openapi.TYPE_ARRAY,
|
||||
items=response_data_schema),
|
||||
"current": openapi.Schema(
|
||||
type=openapi.TYPE_INTEGER,
|
||||
title="当前页",
|
||||
title=_('current page'),
|
||||
default=1,
|
||||
description="当前页"),
|
||||
description=_('current page')),
|
||||
"size": openapi.Schema(
|
||||
type=openapi.TYPE_INTEGER,
|
||||
title="每页大小",
|
||||
title=_('page size'),
|
||||
default=10,
|
||||
description="每页大小")
|
||||
description=_('page size'))
|
||||
|
||||
}
|
||||
)
|
||||
|
|
@ -97,20 +98,20 @@ def get_api_response(response_data_schema: openapi.Schema):
|
|||
"""
|
||||
获取统一返回 响应Api
|
||||
"""
|
||||
return openapi.Responses(responses={200: openapi.Response(description="响应参数",
|
||||
return openapi.Responses(responses={200: openapi.Response(description=_('response parameters'),
|
||||
schema=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'code': openapi.Schema(
|
||||
type=openapi.TYPE_INTEGER,
|
||||
title="响应码",
|
||||
title=_('response code'),
|
||||
default=200,
|
||||
description="成功:200 失败:其他"),
|
||||
description=_('success:200 fail:other')),
|
||||
"message": openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="提示",
|
||||
default='成功',
|
||||
description="错误提示"),
|
||||
title=_('prompt'),
|
||||
default=_('success'),
|
||||
description=_('error prompt')),
|
||||
"data": response_data_schema
|
||||
|
||||
}
|
||||
|
|
@ -126,20 +127,20 @@ def get_api_array_response(response_data_schema: openapi.Schema):
|
|||
"""
|
||||
获取统一返回 响应Api
|
||||
"""
|
||||
return openapi.Responses(responses={200: openapi.Response(description="响应参数",
|
||||
return openapi.Responses(responses={200: openapi.Response(description=_('response parameters'),
|
||||
schema=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'code': openapi.Schema(
|
||||
type=openapi.TYPE_INTEGER,
|
||||
title="响应码",
|
||||
title=_('response code'),
|
||||
default=200,
|
||||
description="成功:200 失败:其他"),
|
||||
description=_('success:200 fail:other')),
|
||||
"message": openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="提示",
|
||||
default='成功',
|
||||
description="错误提示"),
|
||||
title=_('prompt'),
|
||||
default=_('success'),
|
||||
description=_('error prompt')),
|
||||
"data": openapi.Schema(type=openapi.TYPE_ARRAY,
|
||||
items=response_data_schema)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
from drf_yasg import openapi
|
||||
|
||||
from common.mixins.api_mixin import ApiMixin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class CommonApi:
|
||||
|
|
@ -16,31 +17,31 @@ class CommonApi:
|
|||
@staticmethod
|
||||
def get_request_params_api():
|
||||
return [
|
||||
openapi.Parameter(name='query_text',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_STRING,
|
||||
required=True,
|
||||
description='问题文本'),
|
||||
openapi.Parameter(name='top_number',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_NUMBER,
|
||||
default=10,
|
||||
required=True,
|
||||
description='topN'),
|
||||
openapi.Parameter(name='similarity',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_NUMBER,
|
||||
default=0.6,
|
||||
required=True,
|
||||
description='相关性'),
|
||||
openapi.Parameter(name='search_mode',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_STRING,
|
||||
default="embedding",
|
||||
required=True,
|
||||
description='检索模式embedding|keywords|blend'
|
||||
)
|
||||
]
|
||||
openapi.Parameter(name='query_text',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_STRING,
|
||||
required=True,
|
||||
description=_('query text')),
|
||||
openapi.Parameter(name='top_number',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_NUMBER,
|
||||
default=10,
|
||||
required=True,
|
||||
description='topN'),
|
||||
openapi.Parameter(name='similarity',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_NUMBER,
|
||||
default=0.6,
|
||||
required=True,
|
||||
description=_('similarity')),
|
||||
openapi.Parameter(name='search_mode',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_STRING,
|
||||
default="embedding",
|
||||
required=True,
|
||||
description=_('Retrieval pattern embedding|keywords|blend')
|
||||
)
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_response_body_api():
|
||||
|
|
@ -53,31 +54,32 @@ class CommonApi:
|
|||
properties={
|
||||
'id': openapi.Schema(type=openapi.TYPE_STRING, title="id",
|
||||
description="id", default="xx"),
|
||||
'content': openapi.Schema(type=openapi.TYPE_STRING, title="段落内容",
|
||||
description="段落内容", default='段落内容'),
|
||||
'title': openapi.Schema(type=openapi.TYPE_STRING, title="标题",
|
||||
description="标题", default="xxx的描述"),
|
||||
'hit_num': openapi.Schema(type=openapi.TYPE_INTEGER, title="命中数量", description="命中数量",
|
||||
'content': openapi.Schema(type=openapi.TYPE_STRING, title=_('Paragraph content'),
|
||||
description=_('Paragraph content'), default=_('Paragraph content')),
|
||||
'title': openapi.Schema(type=openapi.TYPE_STRING, title=_('title'),
|
||||
description=_('title'), default=_('Description of xxx')),
|
||||
'hit_num': openapi.Schema(type=openapi.TYPE_INTEGER, title=_('Number of hits'),
|
||||
description=_('Number of hits'),
|
||||
default=1),
|
||||
'star_num': openapi.Schema(type=openapi.TYPE_INTEGER, title="点赞数量",
|
||||
description="点赞数量", default=1),
|
||||
'trample_num': openapi.Schema(type=openapi.TYPE_INTEGER, title="点踩数量",
|
||||
description="点踩数", default=1),
|
||||
'dataset_id': openapi.Schema(type=openapi.TYPE_STRING, title="知识库id",
|
||||
description="知识库id", default='xxx'),
|
||||
'document_id': openapi.Schema(type=openapi.TYPE_STRING, title="文档id",
|
||||
description="文档id", default='xxx'),
|
||||
'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title="是否可用",
|
||||
description="是否可用", default=True),
|
||||
'similarity': openapi.Schema(type=openapi.TYPE_NUMBER, title="相关性得分",
|
||||
description="相关性得分", default=True),
|
||||
'comprehensive_score': openapi.Schema(type=openapi.TYPE_NUMBER, title="综合得分,用于排序",
|
||||
description="综合得分,用于排序", default=True),
|
||||
'update_time': openapi.Schema(type=openapi.TYPE_STRING, title="修改时间",
|
||||
description="修改时间",
|
||||
'star_num': openapi.Schema(type=openapi.TYPE_INTEGER, title=_('Number of likes'),
|
||||
description=_('Number of likes'), default=1),
|
||||
'trample_num': openapi.Schema(type=openapi.TYPE_INTEGER, title=_('Number of clicks and dislikes'),
|
||||
description=_('Number of clicks and dislikes'), default=1),
|
||||
'dataset_id': openapi.Schema(type=openapi.TYPE_STRING, title=_('dataset id'),
|
||||
description=_('dataset id'), default='xxx'),
|
||||
'document_id': openapi.Schema(type=openapi.TYPE_STRING, title=_('document id'),
|
||||
description=_('document id'), default='xxx'),
|
||||
'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_('Is active'),
|
||||
description=_('Is active'), default=True),
|
||||
'similarity': openapi.Schema(type=openapi.TYPE_NUMBER, title=_('relevance score'),
|
||||
description=_('relevance score'), default=True),
|
||||
'comprehensive_score': openapi.Schema(type=openapi.TYPE_NUMBER, title=_('Comprehensive score, used for ranking'),
|
||||
description=_('Comprehensive score, used for ranking'), default=True),
|
||||
'update_time': openapi.Schema(type=openapi.TYPE_STRING, title=_('Update time'),
|
||||
description=_('Update time'),
|
||||
default="1970-01-01 00:00:00"),
|
||||
'create_time': openapi.Schema(type=openapi.TYPE_STRING, title="创建时间",
|
||||
description="创建时间",
|
||||
'create_time': openapi.Schema(type=openapi.TYPE_STRING, title=_('Create time'),
|
||||
description=_('Create time'),
|
||||
default="1970-01-01 00:00:00"
|
||||
),
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ from pydub import AudioSegment
|
|||
|
||||
from ..exception.app_exception import AppApiException
|
||||
from ..models.db_model_manage import DBModelManage
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
def sub_array(array: List, item_num=10):
|
||||
result = []
|
||||
|
|
@ -215,9 +215,9 @@ def split_and_transcribe(file_path, model, max_segment_length_ms=59000, audio_fo
|
|||
|
||||
def _remove_empty_lines(text):
|
||||
if not isinstance(text, str):
|
||||
raise AppApiException(500, '文本转语音节点,文本内容必须是字符串类型')
|
||||
raise AppApiException(500, _('Text-to-speech node, the text content must be of string type'))
|
||||
if not text:
|
||||
raise AppApiException(500, '文本转语音节点,文本内容不能为空')
|
||||
raise AppApiException(500, _('Text-to-speech node, the text content cannot be empty'))
|
||||
result = '\n'.join(line for line in text.split('\n') if line.strip())
|
||||
return markdown_to_plain_text(result)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,112 +6,67 @@
|
|||
@date:2024/3/1 14:30
|
||||
@desc:
|
||||
"""
|
||||
from django.utils.translation import gettext_lazy
|
||||
from django.utils.functional import lazy
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
def value_(field, value):
|
||||
return f"【{field}】 {value}"
|
||||
|
||||
|
||||
def reset_messages(field, messages):
|
||||
return {key: lazy(value_, str)(field, messages.get(key)) for key in messages}
|
||||
|
||||
|
||||
def reset_message_by_field(field_text, field):
|
||||
return reset_messages(field_text, {**field.default_error_messages, **field.__bases__[0].default_error_messages})
|
||||
|
||||
|
||||
class ErrMessage:
|
||||
@staticmethod
|
||||
def char(field: str):
|
||||
return {
|
||||
'invalid': gettext_lazy("【%s】不是有效的字符串。" % field),
|
||||
'blank': gettext_lazy("【%s】此字段不能为空字符串。" % field),
|
||||
'max_length': gettext_lazy("【%s】请确保此字段的字符数不超过 {max_length} 个。" % field),
|
||||
'min_length': gettext_lazy("【%s】请确保此字段至少包含 {min_length} 个字符。" % field),
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field)
|
||||
}
|
||||
return reset_message_by_field(field, serializers.CharField)
|
||||
|
||||
@staticmethod
|
||||
def uuid(field: str):
|
||||
return {'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
'invalid': gettext_lazy("【%s】必须是有效的UUID。" % field),
|
||||
}
|
||||
return reset_messages(field, serializers.UUIDField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def integer(field: str):
|
||||
return {'invalid': gettext_lazy('【%s】必须是有效的integer。' % field),
|
||||
'max_value': gettext_lazy('【%s】请确保此值小于或等于 {max_value} 。' % field),
|
||||
'min_value': gettext_lazy('【%s】请确保此值大于或等于 {min_value} 。' % field),
|
||||
'max_string_length': gettext_lazy('【%s】字符串值太大。') % field,
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
}
|
||||
return reset_messages(field, serializers.IntegerField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def list(field: str):
|
||||
return {'not_a_list': gettext_lazy('【%s】应为列表,但得到的类型为 "{input_type}".' % field),
|
||||
'empty': gettext_lazy('【%s】此列表不能为空。' % field),
|
||||
'min_length': gettext_lazy('【%s】请确保此字段至少包含 {min_length} 个元素。' % field),
|
||||
'max_length': gettext_lazy('【%s】请确保此字段的元素不超过 {max_length} 个。' % field),
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
}
|
||||
return reset_messages(field, serializers.ListField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def boolean(field: str):
|
||||
return {'invalid': gettext_lazy('【%s】必须是有效的布尔值。' % field),
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field)}
|
||||
return reset_messages(field, serializers.BooleanField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def dict(field: str):
|
||||
return {'not_a_dict': gettext_lazy('【%s】应为字典,但得到的类型为 "{input_type}' % field),
|
||||
'empty': gettext_lazy('【%s】能是空的。' % field),
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
}
|
||||
return reset_messages(field, serializers.DictField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def float(field: str):
|
||||
return {'invalid': gettext_lazy('【%s】需要一个有效的数字。' % field),
|
||||
'max_value': gettext_lazy('【%s】请确保此值小于或等于 {max_value}。' % field),
|
||||
'min_value': gettext_lazy('【%s】请确保此值大于或等于 {min_value}。' % field),
|
||||
'max_string_length': gettext_lazy('【%s】字符串值太大。' % field),
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
}
|
||||
return reset_messages(field, serializers.FloatField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def json(field: str):
|
||||
return {
|
||||
'invalid': gettext_lazy('【%s】值必须是有效的JSON。' % field),
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
}
|
||||
return reset_messages(field, serializers.JSONField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def base(field: str):
|
||||
return {
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
}
|
||||
return reset_messages(field, serializers.Field.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def date(field: str):
|
||||
return {
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
'invalid': gettext_lazy('【%s】日期格式错误,请改用以下格式之一: {format}。'),
|
||||
'datetime': gettext_lazy('【%s】应为日期,但得到的是日期时间。')
|
||||
}
|
||||
return reset_messages(field, serializers.DateField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def image(field: str):
|
||||
return {
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'null': gettext_lazy('【%s】此字段不能为null。' % field),
|
||||
'invalid_image': gettext_lazy('您上载的【%s】文件不是图像或图像已损坏,请上载有效的图像。' % field),
|
||||
'max_length': gettext_lazy('【%s】请确保此文件名最多包含 {max_length} 个字符(长度为 {length})。' % field),
|
||||
'invalid': gettext_lazy('【%s】提交的数据不是文件,请检查表单上的编码类型。' % field)
|
||||
}
|
||||
return reset_messages(field, serializers.ImageField.default_error_messages)
|
||||
|
||||
@staticmethod
|
||||
def file(field: str):
|
||||
return {
|
||||
'required': gettext_lazy('【%s】此字段必填。' % field),
|
||||
'empty': gettext_lazy('【%s】提交的文件为空。' % field),
|
||||
'invalid': gettext_lazy('【%s】提交的数据不是文件,请检查表单上的编码类型。' % field),
|
||||
'no_name': gettext_lazy('【%s】无法确定任何文件名。' % field),
|
||||
'max_length': gettext_lazy('【%s】请确保此文件名最多包含 {max_length} 个字符(长度为 {length})。' % field)
|
||||
}
|
||||
return reset_messages(field, serializers.FileField.default_error_messages)
|
||||
|
|
|
|||
|
|
@ -20,13 +20,17 @@ from dataset.models import Document, TaskType, State
|
|||
from ops import celery_app
|
||||
from setting.models import Model
|
||||
from setting.models_provider import get_model
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
max_kb_error = logging.getLogger("max_kb_error")
|
||||
max_kb = logging.getLogger("max_kb")
|
||||
|
||||
|
||||
def get_embedding_model(model_id, exception_handler=lambda e: max_kb_error.error(
|
||||
f'获取向量模型失败:{str(e)}{traceback.format_exc()}')):
|
||||
_('Failed to obtain vector model: {error} {traceback}').format(
|
||||
error=str(e),
|
||||
traceback=traceback.format_exc()
|
||||
))):
|
||||
try:
|
||||
model = QuerySet(Model).filter(id=model_id).first()
|
||||
embedding_model = ModelManage.get_model(model_id,
|
||||
|
|
@ -74,7 +78,10 @@ def embedding_by_document(document_id, model_id, state_list=None):
|
|||
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id), TaskType.EMBEDDING,
|
||||
State.FAILURE)
|
||||
max_kb_error.error(
|
||||
f'获取向量模型失败:{str(e)}{traceback.format_exc()}')
|
||||
_('Failed to obtain vector model: {error} {traceback}').format(
|
||||
error=str(e),
|
||||
traceback=traceback.format_exc()
|
||||
))
|
||||
|
||||
embedding_model = get_embedding_model(model_id, exception_handler)
|
||||
ListenerManagement.embedding_by_document(document_id, embedding_model, state_list)
|
||||
|
|
@ -100,20 +107,24 @@ def embedding_by_dataset(dataset_id, model_id):
|
|||
@param model_id 向量模型
|
||||
:return: None
|
||||
"""
|
||||
max_kb.info(f"开始--->向量化数据集:{dataset_id}")
|
||||
max_kb.info(_('Start--->Vectorized dataset: {dataset_id}').format(dataset_id=dataset_id))
|
||||
try:
|
||||
ListenerManagement.delete_embedding_by_dataset(dataset_id)
|
||||
document_list = QuerySet(Document).filter(dataset_id=dataset_id)
|
||||
max_kb.info(f"数据集文档:{[d.name for d in document_list]}")
|
||||
max_kb.info(_('Dataset documentation: {document_names}').format(
|
||||
document_names=", ".join([d.name for d in document_list])))
|
||||
for document in document_list:
|
||||
try:
|
||||
embedding_by_document.delay(document.id, model_id)
|
||||
except Exception as e:
|
||||
pass
|
||||
except Exception as e:
|
||||
max_kb_error.error(f'向量化数据集:{dataset_id}出现错误{str(e)}{traceback.format_exc()}')
|
||||
max_kb_error.error(
|
||||
_('Vectorized dataset: {dataset_id} error {error} {traceback}'.format(dataset_id=dataset_id,
|
||||
error=str(e),
|
||||
traceback=traceback.format_exc())))
|
||||
finally:
|
||||
max_kb.info(f"结束--->向量化数据集:{dataset_id}")
|
||||
max_kb.info(_('End--->Vectorized dataset: {dataset_id}').format(dataset_id=dataset_id))
|
||||
|
||||
|
||||
def embedding_by_problem(args, model_id):
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ from common.util.field_message import ErrMessage
|
|||
from common.util.function_code import FunctionExecutor
|
||||
from function_lib.models.function import FunctionLib
|
||||
from smartdoc.const import CONFIG
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
function_executor = FunctionExecutor(CONFIG.get('SANDBOX'))
|
||||
|
||||
|
|
@ -32,72 +33,72 @@ class FunctionLibModelSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class FunctionLibInputField(serializers.Serializer):
|
||||
name = serializers.CharField(required=True, error_messages=ErrMessage.char('变量名'))
|
||||
is_required = serializers.BooleanField(required=True, error_messages=ErrMessage.boolean("是否必填"))
|
||||
type = serializers.CharField(required=True, error_messages=ErrMessage.char("类型"), validators=[
|
||||
name = serializers.CharField(required=True, error_messages=ErrMessage.char(_('variable name')))
|
||||
is_required = serializers.BooleanField(required=True, error_messages=ErrMessage.boolean(_('required')))
|
||||
type = serializers.CharField(required=True, error_messages=ErrMessage.char(_('type')), validators=[
|
||||
validators.RegexValidator(regex=re.compile("^string|int|dict|array|float$"),
|
||||
message="字段只支持string|int|dict|array|float", code=500)
|
||||
message=_('fields only support string|int|dict|array|float'), code=500)
|
||||
])
|
||||
source = serializers.CharField(required=True, error_messages=ErrMessage.char("来源"), validators=[
|
||||
source = serializers.CharField(required=True, error_messages=ErrMessage.char(_('source')), validators=[
|
||||
validators.RegexValidator(regex=re.compile("^custom|reference$"),
|
||||
message="字段只支持custom|reference", code=500)
|
||||
message=_('The field only supports custom|reference'), code=500)
|
||||
])
|
||||
|
||||
|
||||
class DebugField(serializers.Serializer):
|
||||
name = serializers.CharField(required=True, error_messages=ErrMessage.char('变量名'))
|
||||
name = serializers.CharField(required=True, error_messages=ErrMessage.char(_('variable name')))
|
||||
value = serializers.CharField(required=False, allow_blank=True, allow_null=True,
|
||||
error_messages=ErrMessage.char("变量值"))
|
||||
error_messages=ErrMessage.char(_('variable value')))
|
||||
|
||||
|
||||
class DebugInstance(serializers.Serializer):
|
||||
debug_field_list = DebugField(required=True, many=True)
|
||||
input_field_list = FunctionLibInputField(required=True, many=True)
|
||||
code = serializers.CharField(required=True, error_messages=ErrMessage.char("函数内容"))
|
||||
code = serializers.CharField(required=True, error_messages=ErrMessage.char(_('function content')))
|
||||
|
||||
|
||||
class EditFunctionLib(serializers.Serializer):
|
||||
name = serializers.CharField(required=False, allow_null=True, allow_blank=True,
|
||||
error_messages=ErrMessage.char("函数名称"))
|
||||
error_messages=ErrMessage.char(_('function name')))
|
||||
|
||||
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True,
|
||||
error_messages=ErrMessage.char("函数描述"))
|
||||
error_messages=ErrMessage.char(_('function description')))
|
||||
|
||||
code = serializers.CharField(required=False, allow_null=True, allow_blank=True,
|
||||
error_messages=ErrMessage.char("函数内容"))
|
||||
error_messages=ErrMessage.char(_('function content')))
|
||||
|
||||
input_field_list = FunctionLibInputField(required=False, many=True)
|
||||
|
||||
is_active = serializers.BooleanField(required=False, error_messages=ErrMessage.char('是否可用'))
|
||||
is_active = serializers.BooleanField(required=False, error_messages=ErrMessage.char(_('Is active')))
|
||||
|
||||
|
||||
class CreateFunctionLib(serializers.Serializer):
|
||||
name = serializers.CharField(required=True, error_messages=ErrMessage.char("函数名称"))
|
||||
name = serializers.CharField(required=True, error_messages=ErrMessage.char(_('function name')))
|
||||
|
||||
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True,
|
||||
error_messages=ErrMessage.char("函数描述"))
|
||||
error_messages=ErrMessage.char(_('function description')))
|
||||
|
||||
code = serializers.CharField(required=True, error_messages=ErrMessage.char("函数内容"))
|
||||
code = serializers.CharField(required=True, error_messages=ErrMessage.char(_('function content')))
|
||||
|
||||
input_field_list = FunctionLibInputField(required=True, many=True)
|
||||
|
||||
permission_type = serializers.CharField(required=True, error_messages=ErrMessage.char("权限"), validators=[
|
||||
permission_type = serializers.CharField(required=True, error_messages=ErrMessage.char(_('permission')), validators=[
|
||||
validators.RegexValidator(regex=re.compile("^PUBLIC|PRIVATE$"),
|
||||
message="权限只支持PUBLIC|PRIVATE", code=500)
|
||||
])
|
||||
is_active = serializers.BooleanField(required=False, error_messages=ErrMessage.char('是否可用'))
|
||||
is_active = serializers.BooleanField(required=False, error_messages=ErrMessage.char(_('Is active')))
|
||||
|
||||
|
||||
class FunctionLibSerializer(serializers.Serializer):
|
||||
class Query(serializers.Serializer):
|
||||
name = serializers.CharField(required=False, allow_null=True, allow_blank=True,
|
||||
error_messages=ErrMessage.char("函数名称"))
|
||||
error_messages=ErrMessage.char(_('function name')))
|
||||
|
||||
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True,
|
||||
error_messages=ErrMessage.char("函数描述"))
|
||||
is_active = serializers.BooleanField(required=False, error_messages=ErrMessage.char("是否可用"))
|
||||
error_messages=ErrMessage.char(_('function description')))
|
||||
is_active = serializers.BooleanField(required=False, error_messages=ErrMessage.char(_('Is active')))
|
||||
|
||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid("用户id"))
|
||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('user id')))
|
||||
select_user_id = serializers.CharField(required=False, allow_null=True, allow_blank=True)
|
||||
|
||||
def get_query_set(self):
|
||||
|
|
@ -126,7 +127,7 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||
post_records_handler=lambda row: FunctionLibModelSerializer(row).data)
|
||||
|
||||
class Create(serializers.Serializer):
|
||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid("用户id"))
|
||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('user id')))
|
||||
|
||||
def insert(self, instance, with_valid=True):
|
||||
if with_valid:
|
||||
|
|
@ -142,7 +143,7 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||
return FunctionLibModelSerializer(function_lib).data
|
||||
|
||||
class Debug(serializers.Serializer):
|
||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid("用户id"))
|
||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('user id')))
|
||||
|
||||
def debug(self, debug_instance, with_valid=True):
|
||||
if with_valid:
|
||||
|
|
@ -165,7 +166,7 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||
if len(result) > 0:
|
||||
return result[-1].get('value')
|
||||
if is_required:
|
||||
raise AppApiException(500, f"{name}字段未设置值")
|
||||
raise AppApiException(500, f"{name}" + _('field has no value set'))
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -181,24 +182,26 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||
v = json.loads(value)
|
||||
if isinstance(v, dict):
|
||||
return v
|
||||
raise Exception("类型错误")
|
||||
raise Exception(_('type error'))
|
||||
if _type == 'array':
|
||||
v = json.loads(value)
|
||||
if isinstance(v, list):
|
||||
return v
|
||||
raise Exception("类型错误")
|
||||
raise Exception(_('type error'))
|
||||
return value
|
||||
except Exception as e:
|
||||
raise AppApiException(500, f'字段:{name}类型:{_type}值:{value}类型转换错误')
|
||||
raise AppApiException(500, _('Field: {name} Type: {_type} Value: {value} Type conversion error').format(
|
||||
name=name, type=_type, value=value
|
||||
))
|
||||
|
||||
class Operate(serializers.Serializer):
|
||||
id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid("函数id"))
|
||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid("用户id"))
|
||||
id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('function id')))
|
||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('user id')))
|
||||
|
||||
def is_valid(self, *, raise_exception=False):
|
||||
super().is_valid(raise_exception=True)
|
||||
if not QuerySet(FunctionLib).filter(id=self.data.get('id'), user_id=self.data.get('user_id')).exists():
|
||||
raise AppApiException(500, '函数不存在')
|
||||
raise AppApiException(500, _('Function does not exist'))
|
||||
|
||||
def delete(self, with_valid=True):
|
||||
if with_valid:
|
||||
|
|
@ -221,6 +224,6 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||
super().is_valid(raise_exception=True)
|
||||
if not QuerySet(FunctionLib).filter(id=self.data.get('id')).filter(
|
||||
Q(user_id=self.data.get('user_id')) | Q(permission_type='PUBLIC')).exists():
|
||||
raise AppApiException(500, '函数不存在')
|
||||
raise AppApiException(500, _('Function does not exist'))
|
||||
function_lib = QuerySet(FunctionLib).filter(id=self.data.get('id')).first()
|
||||
return FunctionLibModelSerializer(function_lib).data
|
||||
|
|
|
|||
|
|
@ -15,11 +15,12 @@ from rest_framework import serializers
|
|||
|
||||
from common.util.field_message import ErrMessage
|
||||
from smartdoc.const import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class PyLintInstance(serializers.Serializer):
|
||||
code = serializers.CharField(required=True, allow_null=True, allow_blank=True,
|
||||
error_messages=ErrMessage.char("函数内容"))
|
||||
error_messages=ErrMessage.char(_('function content')))
|
||||
|
||||
|
||||
def to_dict(message, file_name):
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
from drf_yasg import openapi
|
||||
|
||||
from common.mixins.api_mixin import ApiMixin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class FunctionLibApi(ApiMixin):
|
||||
|
|
@ -19,13 +20,19 @@ class FunctionLibApi(ApiMixin):
|
|||
required=['id', 'name', 'desc', 'code', 'input_field_list', 'create_time',
|
||||
'update_time'],
|
||||
properties={
|
||||
'id': openapi.Schema(type=openapi.TYPE_STRING, title="", description="主键id"),
|
||||
'name': openapi.Schema(type=openapi.TYPE_STRING, title="函数名称", description="函数名称"),
|
||||
'desc': openapi.Schema(type=openapi.TYPE_STRING, title="函数描述", description="函数描述"),
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title="函数内容", description="函数内容"),
|
||||
'input_field_list': openapi.Schema(type=openapi.TYPE_STRING, title="输入字段", description="输入字段"),
|
||||
'create_time': openapi.Schema(type=openapi.TYPE_STRING, title="创建时间", description="创建时间"),
|
||||
'update_time': openapi.Schema(type=openapi.TYPE_STRING, title="修改时间", description="修改时间"),
|
||||
'id': openapi.Schema(type=openapi.TYPE_STRING, title="", description=_('ID')),
|
||||
'name': openapi.Schema(type=openapi.TYPE_STRING, title=_('function name'),
|
||||
description=_('function name')),
|
||||
'desc': openapi.Schema(type=openapi.TYPE_STRING, title=_('function description'),
|
||||
description=_('function description')),
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title=_('function content'),
|
||||
description=_('function content')),
|
||||
'input_field_list': openapi.Schema(type=openapi.TYPE_STRING, title=_('input field'),
|
||||
description=_('input field')),
|
||||
'create_time': openapi.Schema(type=openapi.TYPE_STRING, title=_('create time'),
|
||||
description=_('create time')),
|
||||
'update_time': openapi.Schema(type=openapi.TYPE_STRING, title=_('update time'),
|
||||
description=_('update time')),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -36,12 +43,12 @@ class FunctionLibApi(ApiMixin):
|
|||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_STRING,
|
||||
required=False,
|
||||
description='函数名称'),
|
||||
description=_('function name')),
|
||||
openapi.Parameter(name='desc',
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_STRING,
|
||||
required=False,
|
||||
description='函数描述')
|
||||
description=_('function description')),
|
||||
]
|
||||
|
||||
class Debug(ApiMixin):
|
||||
|
|
@ -52,42 +59,45 @@ class FunctionLibApi(ApiMixin):
|
|||
required=[],
|
||||
properties={
|
||||
'debug_field_list': openapi.Schema(type=openapi.TYPE_ARRAY,
|
||||
description="输入变量列表",
|
||||
description=_('Input variable list'),
|
||||
items=openapi.Schema(type=openapi.TYPE_OBJECT,
|
||||
required=[],
|
||||
properties={
|
||||
'name': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="变量名",
|
||||
description="变量名"),
|
||||
title=_('variable name'),
|
||||
description=_('variable name')),
|
||||
'value': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="变量值",
|
||||
description="变量值"),
|
||||
title=_('variable value'),
|
||||
description=_('variable value')),
|
||||
})),
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title="函数内容", description="函数内容"),
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title=_('function content'),
|
||||
description=_('function content')),
|
||||
'input_field_list': openapi.Schema(type=openapi.TYPE_ARRAY,
|
||||
description="输入变量列表",
|
||||
description=_('Input variable list'),
|
||||
items=openapi.Schema(type=openapi.TYPE_OBJECT,
|
||||
required=['name', 'is_required', 'source'],
|
||||
properties={
|
||||
'name': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="变量名",
|
||||
description="变量名"),
|
||||
title=_('variable name'),
|
||||
description=_('variable name')),
|
||||
'is_required': openapi.Schema(
|
||||
type=openapi.TYPE_BOOLEAN,
|
||||
title="是否必填",
|
||||
description="是否必填"),
|
||||
title=_('required'),
|
||||
description=_('required')),
|
||||
'type': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="字段类型",
|
||||
description="字段类型 string|int|dict|array|float"
|
||||
title=_('type'),
|
||||
description=_(
|
||||
'Field type string|int|dict|array|float')
|
||||
),
|
||||
'source': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="来源",
|
||||
description="来源只支持custom|reference"),
|
||||
title=_('source'),
|
||||
description=_(
|
||||
'The source only supports custom|reference')),
|
||||
|
||||
}))
|
||||
}
|
||||
|
|
@ -100,33 +110,40 @@ class FunctionLibApi(ApiMixin):
|
|||
type=openapi.TYPE_OBJECT,
|
||||
required=[],
|
||||
properties={
|
||||
'name': openapi.Schema(type=openapi.TYPE_STRING, title="函数名称", description="函数名称"),
|
||||
'desc': openapi.Schema(type=openapi.TYPE_STRING, title="函数描述", description="函数描述"),
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title="函数内容", description="函数内容"),
|
||||
'permission_type': openapi.Schema(type=openapi.TYPE_STRING, title="权限", description="权限"),
|
||||
'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title="是否可用", description="是否可用"),
|
||||
'name': openapi.Schema(type=openapi.TYPE_STRING, title=_('function name'),
|
||||
description=_('function name')),
|
||||
'desc': openapi.Schema(type=openapi.TYPE_STRING, title=_('function description'),
|
||||
description=_('function description')),
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title=_('function content'),
|
||||
description=_('function content')),
|
||||
'permission_type': openapi.Schema(type=openapi.TYPE_STRING, title=_('permission'),
|
||||
description=_('permission')),
|
||||
'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_('Is active'),
|
||||
description=_('Is active')),
|
||||
'input_field_list': openapi.Schema(type=openapi.TYPE_ARRAY,
|
||||
description="输入变量列表",
|
||||
description=_('Input variable list'),
|
||||
items=openapi.Schema(type=openapi.TYPE_OBJECT,
|
||||
required=[],
|
||||
properties={
|
||||
'name': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="变量名",
|
||||
description="变量名"),
|
||||
title=_('variable name'),
|
||||
description=_('variable name')),
|
||||
'is_required': openapi.Schema(
|
||||
type=openapi.TYPE_BOOLEAN,
|
||||
title="是否必填",
|
||||
description="是否必填"),
|
||||
title=_('required'),
|
||||
description=_('required')),
|
||||
'type': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="字段类型",
|
||||
description="字段类型 string|int|dict|array|float"
|
||||
title=_('type'),
|
||||
description=_(
|
||||
'Field type string|int|dict|array|float')
|
||||
),
|
||||
'source': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="来源",
|
||||
description="来源只支持custom|reference"),
|
||||
title=_('source'),
|
||||
description=_(
|
||||
'The source only supports custom|reference')),
|
||||
|
||||
}))
|
||||
}
|
||||
|
|
@ -139,33 +156,40 @@ class FunctionLibApi(ApiMixin):
|
|||
type=openapi.TYPE_OBJECT,
|
||||
required=['name', 'code', 'input_field_list', 'permission_type'],
|
||||
properties={
|
||||
'name': openapi.Schema(type=openapi.TYPE_STRING, title="函数名称", description="函数名称"),
|
||||
'desc': openapi.Schema(type=openapi.TYPE_STRING, title="函数描述", description="函数描述"),
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title="函数内容", description="函数内容"),
|
||||
'permission_type': openapi.Schema(type=openapi.TYPE_STRING, title="权限", description="权限"),
|
||||
'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title="是否可用", description="是否可用"),
|
||||
'name': openapi.Schema(type=openapi.TYPE_STRING, title=_('function name'),
|
||||
description=_('function name')),
|
||||
'desc': openapi.Schema(type=openapi.TYPE_STRING, title=_('function description'),
|
||||
description=_('function description')),
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title=_('function content'),
|
||||
description=_('function content')),
|
||||
'permission_type': openapi.Schema(type=openapi.TYPE_STRING, title=_('permission'),
|
||||
description=_('permission')),
|
||||
'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_('Is active'),
|
||||
description=_('Is active')),
|
||||
'input_field_list': openapi.Schema(type=openapi.TYPE_ARRAY,
|
||||
description="输入变量列表",
|
||||
description=_('Input variable list'),
|
||||
items=openapi.Schema(type=openapi.TYPE_OBJECT,
|
||||
required=['name', 'is_required', 'source'],
|
||||
properties={
|
||||
'name': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="变量名",
|
||||
description="变量名"),
|
||||
title=_('variable name'),
|
||||
description=_('variable name')),
|
||||
'is_required': openapi.Schema(
|
||||
type=openapi.TYPE_BOOLEAN,
|
||||
title="是否必填",
|
||||
description="是否必填"),
|
||||
title=_('required'),
|
||||
description=_('required')),
|
||||
'type': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="字段类型",
|
||||
description="字段类型 string|int|dict|array|float"
|
||||
title=_('type'),
|
||||
description=_(
|
||||
'Field type string|int|dict|array|float')
|
||||
),
|
||||
'source': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
title="来源",
|
||||
description="来源只支持custom|reference"),
|
||||
title=_('source'),
|
||||
description=_(
|
||||
'The source only supports custom|reference')),
|
||||
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
from drf_yasg import openapi
|
||||
|
||||
from common.mixins.api_mixin import ApiMixin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class PyLintApi(ApiMixin):
|
||||
|
|
@ -18,6 +19,7 @@ class PyLintApi(ApiMixin):
|
|||
type=openapi.TYPE_OBJECT,
|
||||
required=['code'],
|
||||
properties={
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title="函数内容", description="函数内容")
|
||||
'code': openapi.Schema(type=openapi.TYPE_STRING, title=_('function content'),
|
||||
description=_('function content'))
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,15 +16,16 @@ from common.constants.permission_constants import RoleConstants
|
|||
from common.response import result
|
||||
from function_lib.serializers.function_lib_serializer import FunctionLibSerializer
|
||||
from function_lib.swagger_api.function_lib_api import FunctionLibApi
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class FunctionLibView(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
@action(methods=["GET"], detail=False)
|
||||
@swagger_auto_schema(operation_summary="获取函数列表",
|
||||
operation_id="获取函数列表",
|
||||
tags=["函数库"],
|
||||
@swagger_auto_schema(operation_summary=_('Get function list'),
|
||||
operation_id=_('Get function list'),
|
||||
tags=[_('Function')],
|
||||
manual_parameters=FunctionLibApi.Query.get_request_params_api())
|
||||
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||
def get(self, request: Request):
|
||||
|
|
@ -35,10 +36,10 @@ class FunctionLibView(APIView):
|
|||
'user_id': request.user.id}).list())
|
||||
|
||||
@action(methods=['POST'], detail=False)
|
||||
@swagger_auto_schema(operation_summary="创建函数",
|
||||
operation_id="创建函数",
|
||||
@swagger_auto_schema(operation_summary=_('Create function'),
|
||||
operation_id=_('Create function'),
|
||||
request_body=FunctionLibApi.Create.get_request_body_api(),
|
||||
tags=['函数库'])
|
||||
tags=[_('Function')])
|
||||
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||
def post(self, request: Request):
|
||||
return result.success(FunctionLibSerializer.Create(data={'user_id': request.user.id}).insert(request.data))
|
||||
|
|
@ -47,10 +48,10 @@ class FunctionLibView(APIView):
|
|||
authentication_classes = [TokenAuth]
|
||||
|
||||
@action(methods=['POST'], detail=False)
|
||||
@swagger_auto_schema(operation_summary="调试函数",
|
||||
operation_id="调试函数",
|
||||
@swagger_auto_schema(operation_summary=_('Debug function'),
|
||||
operation_id=_('Debug function'),
|
||||
request_body=FunctionLibApi.Debug.get_request_body_api(),
|
||||
tags=['函数库'])
|
||||
tags=[_('Function')])
|
||||
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||
def post(self, request: Request):
|
||||
return result.success(
|
||||
|
|
@ -61,10 +62,10 @@ class FunctionLibView(APIView):
|
|||
authentication_classes = [TokenAuth]
|
||||
|
||||
@action(methods=['PUT'], detail=False)
|
||||
@swagger_auto_schema(operation_summary="修改函数",
|
||||
operation_id="修改函数",
|
||||
@swagger_auto_schema(operation_summary=_('Update function'),
|
||||
operation_id=_('Update function'),
|
||||
request_body=FunctionLibApi.Edit.get_request_body_api(),
|
||||
tags=['函数库'])
|
||||
tags=[_('Function')])
|
||||
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||
def put(self, request: Request, function_lib_id: str):
|
||||
return result.success(
|
||||
|
|
@ -72,18 +73,18 @@ class FunctionLibView(APIView):
|
|||
request.data))
|
||||
|
||||
@action(methods=['DELETE'], detail=False)
|
||||
@swagger_auto_schema(operation_summary="删除函数",
|
||||
operation_id="删除函数",
|
||||
tags=['函数库'])
|
||||
@swagger_auto_schema(operation_summary=_('Delete function'),
|
||||
operation_id=_('Delete function'),
|
||||
tags=[_('Function')])
|
||||
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||
def delete(self, request: Request, function_lib_id: str):
|
||||
return result.success(
|
||||
FunctionLibSerializer.Operate(data={'user_id': request.user.id, 'id': function_lib_id}).delete())
|
||||
|
||||
@action(methods=['GET'], detail=False)
|
||||
@swagger_auto_schema(operation_summary="获取函数详情",
|
||||
operation_id="获取函数详情",
|
||||
tags=['函数库'])
|
||||
@swagger_auto_schema(operation_summary=_('Get function details'),
|
||||
operation_id=_('Get function details'),
|
||||
tags=[_('Function')])
|
||||
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||
def get(self, request: Request, function_lib_id: str):
|
||||
return result.success(
|
||||
|
|
@ -93,12 +94,12 @@ class FunctionLibView(APIView):
|
|||
authentication_classes = [TokenAuth]
|
||||
|
||||
@action(methods=['GET'], detail=False)
|
||||
@swagger_auto_schema(operation_summary="分页获取函数列表",
|
||||
operation_id="分页获取函数列表",
|
||||
@swagger_auto_schema(operation_summary=_('Get function list by pagination'),
|
||||
operation_id=_('Get function list by pagination'),
|
||||
manual_parameters=result.get_page_request_params(
|
||||
FunctionLibApi.Query.get_request_params_api()),
|
||||
responses=result.get_page_api_response(FunctionLibApi.get_response_body_api()),
|
||||
tags=['函数库'])
|
||||
tags=[_('Function')])
|
||||
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||
def get(self, request: Request, current_page: int, page_size: int):
|
||||
return result.success(
|
||||
|
|
|
|||
|
|
@ -16,16 +16,17 @@ from common.constants.permission_constants import RoleConstants
|
|||
from common.response import result
|
||||
from function_lib.serializers.py_lint_serializer import PyLintSerializer
|
||||
from function_lib.swagger_api.py_lint_api import PyLintApi
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class PyLintView(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
@action(methods=['POST'], detail=False)
|
||||
@swagger_auto_schema(operation_summary="校验代码",
|
||||
operation_id="校验代码",
|
||||
@swagger_auto_schema(operation_summary=_('Check code'),
|
||||
operation_id=_('Check code'),
|
||||
request_body=PyLintApi.get_request_body_api(),
|
||||
tags=['函数库'])
|
||||
tags=[_('Function')])
|
||||
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||
def post(self, request: Request):
|
||||
return result.success(PyLintSerializer(data={'user_id': request.user.id}).pylint(request.data))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-01-06 09:58+0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: .\apps\application\serializers\application_serializers.py:196
|
||||
msgid "application name"
|
||||
msgstr ""
|
||||
|
||||
#: .\apps\application\serializers\application_serializers.py:199
|
||||
msgid "application describe"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-01-06 09:58+0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: .\apps\application\serializers\application_serializers.py:196
|
||||
msgid "application name"
|
||||
msgstr ""
|
||||
|
||||
#: .\apps\application\serializers\application_serializers.py:199
|
||||
msgid "application describe"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-01-06 09:58+0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
#: .\apps\application\serializers\application_serializers.py:196
|
||||
msgid "application name"
|
||||
msgstr ""
|
||||
|
||||
#: .\apps\application\serializers\application_serializers.py:199
|
||||
msgid "application describe"
|
||||
msgstr ""
|
||||
|
|
@ -14,7 +14,7 @@ from typing import Dict, Iterator, Type, List
|
|||
from pydantic.v1 import BaseModel
|
||||
|
||||
from common.exception.app_exception import AppApiException
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class DownModelChunkStatus(Enum):
|
||||
success = "success"
|
||||
|
|
@ -60,7 +60,7 @@ class IModelProvider(ABC):
|
|||
|
||||
def get_model_list(self, model_type):
|
||||
if model_type is None:
|
||||
raise AppApiException(500, '模型类型不能为空')
|
||||
raise AppApiException(500, _('Model type cannot be empty'))
|
||||
return self.get_model_info_manage().get_model_list_by_model_type(model_type)
|
||||
|
||||
def get_model_credential(self, model_type, model_name):
|
||||
|
|
@ -84,7 +84,7 @@ class IModelProvider(ABC):
|
|||
return 3
|
||||
|
||||
def down_model(self, model_type: str, model_name, model_credential: Dict[str, object]) -> Iterator[DownModelChunk]:
|
||||
raise AppApiException(500, "当前平台不支持下载模型")
|
||||
raise AppApiException(500, _('The current platform does not support downloading models'))
|
||||
|
||||
|
||||
class MaxKBBaseModel(ABC):
|
||||
|
|
@ -149,13 +149,13 @@ class BaseModelCredential(ABC):
|
|||
|
||||
|
||||
class ModelTypeConst(Enum):
|
||||
LLM = {'code': 'LLM', 'message': '大语言模型'}
|
||||
EMBEDDING = {'code': 'EMBEDDING', 'message': '向量模型'}
|
||||
STT = {'code': 'STT', 'message': '语音识别'}
|
||||
TTS = {'code': 'TTS', 'message': '语音合成'}
|
||||
IMAGE = {'code': 'IMAGE', 'message': '图片理解'}
|
||||
TTI = {'code': 'TTI', 'message': '图片生成'}
|
||||
RERANKER = {'code': 'RERANKER', 'message': '重排模型'}
|
||||
LLM = {'code': 'LLM', 'message': _('large language model')}
|
||||
EMBEDDING = {'code': 'EMBEDDING', 'message': _('vector model')}
|
||||
STT = {'code': 'STT', 'message': _('speech to text')}
|
||||
TTS = {'code': 'TTS', 'message': _('text to speech')}
|
||||
IMAGE = {'code': 'IMAGE', 'message': _('picture understanding')}
|
||||
TTI = {'code': 'TTI', 'message': _('text to image')}
|
||||
RERANKER = {'code': 'RERANKER', 'message': _('re-ranking')}
|
||||
|
||||
|
||||
class ModelInfo:
|
||||
|
|
@ -229,7 +229,7 @@ class ModelInfoManage:
|
|||
def get_model_info(self, model_type, model_name) -> ModelInfo:
|
||||
model_info = self.model_dict.get(model_type, {}).get(model_name, self.default_model_dict.get(model_type))
|
||||
if model_info is None:
|
||||
raise AppApiException(500, '模型不支持')
|
||||
raise AppApiException(500, _('The model does not support'))
|
||||
return model_info
|
||||
|
||||
class builder:
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ from setting.models_provider.impl.aliyun_bai_lian_model_provider.model.stt impor
|
|||
from setting.models_provider.impl.aliyun_bai_lian_model_provider.model.tti import QwenTextToImageModel
|
||||
from setting.models_provider.impl.aliyun_bai_lian_model_provider.model.tts import AliyunBaiLianTextToSpeech
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
aliyun_bai_lian_model_credential = AliyunBaiLianRerankerCredential()
|
||||
aliyun_bai_lian_tts_model_credential = AliyunBaiLianTTSModelCredential()
|
||||
|
|
@ -38,16 +39,18 @@ qwenvl_model_credential = QwenVLModelCredential()
|
|||
qwentti_model_credential = QwenTextToImageModelCredential()
|
||||
|
||||
model_info_list = [ModelInfo('gte-rerank',
|
||||
'阿里巴巴通义实验室开发的GTE-Rerank文本排序系列模型,开发者可以通过LlamaIndex框架进行集成高质量文本检索、排序。',
|
||||
_('With the GTE-Rerank text sorting series model developed by Alibaba Tongyi Lab, developers can integrate high-quality text retrieval and sorting through the LlamaIndex framework.'),
|
||||
ModelTypeConst.RERANKER, aliyun_bai_lian_model_credential, AliyunBaiLianReranker),
|
||||
ModelInfo('paraformer-realtime-v2',
|
||||
'中文(含粤语等各种方言)、英文、日语、韩语支持多个语种自由切换',
|
||||
_('Chinese (including various dialects such as Cantonese), English, Japanese, and Korean support free switching between multiple languages.'),
|
||||
ModelTypeConst.STT, aliyun_bai_lian_stt_model_credential, AliyunBaiLianSpeechToText),
|
||||
ModelInfo('cosyvoice-v1',
|
||||
'CosyVoice基于新一代生成式语音大模型,能根据上下文预测情绪、语调、韵律等,具有更好的拟人效果',
|
||||
_('CosyVoice is based on a new generation of large generative speech models, which can predict emotions, intonation, rhythm, etc. based on context, and has better anthropomorphic effects.'),
|
||||
ModelTypeConst.TTS, aliyun_bai_lian_tts_model_credential, AliyunBaiLianTextToSpeech),
|
||||
ModelInfo('text-embedding-v1',
|
||||
'通用文本向量,是通义实验室基于LLM底座的多语言文本统一向量模型,面向全球多个主流语种,提供高水准的向量服务,帮助开发者将文本数据快速转换为高质量的向量数据。',
|
||||
_('''
|
||||
Universal text vector is Tongyi Lab's multi-language text unified vector model based on the LLM base. It provides high-level vector services for multiple mainstream languages around the world and helps developers quickly convert text data into high-quality vector data.
|
||||
'''),
|
||||
ModelTypeConst.EMBEDDING, aliyun_bai_lian_embedding_model_credential,
|
||||
AliyunBaiLianEmbedding),
|
||||
ModelInfo('qwen-turbo', '', ModelTypeConst.LLM, aliyun_bai_lian_llm_model_credential,
|
||||
|
|
@ -65,7 +68,7 @@ module_info_vl_list = [
|
|||
]
|
||||
module_info_tti_list = [
|
||||
ModelInfo('wanx-v1',
|
||||
'通义万相-文本生成图像大模型,支持中英文双语输入,支持输入参考图片进行参考内容或者参考风格迁移,重点风格包括但不限于水彩、油画、中国画、素描、扁平插画、二次元、3D卡通。',
|
||||
_('Tongyi Wanxiang - a large image model for text generation, supports bilingual input in Chinese and English, and supports the input of reference pictures for reference content or reference style migration. Key styles include but are not limited to watercolor, oil painting, Chinese painting, sketch, flat illustration, two-dimensional, and 3D. Cartoon.'),
|
||||
ModelTypeConst.TTI, qwentti_model_credential, QwenTextToImageModel),
|
||||
]
|
||||
|
||||
|
|
@ -90,7 +93,9 @@ class AliyunBaiLianModelProvider(IModelProvider):
|
|||
return model_info_manage
|
||||
|
||||
def get_model_provide_info(self):
|
||||
return ModelProvideInfo(provider='aliyun_bai_lian_model_provider', name='阿里云百炼', icon=get_file_content(
|
||||
os.path.join(PROJECT_DIR, "apps", "setting", 'models_provider', 'impl', 'aliyun_bai_lian_model_provider',
|
||||
'icon',
|
||||
'aliyun_bai_lian_icon_svg')))
|
||||
return ModelProvideInfo(provider='aliyun_bai_lian_model_provider', name=_('Alibaba Cloud Bailian'),
|
||||
icon=get_file_content(
|
||||
os.path.join(PROJECT_DIR, "apps", "setting", 'models_provider', 'impl',
|
||||
'aliyun_bai_lian_model_provider',
|
||||
'icon',
|
||||
'aliyun_bai_lian_icon_svg')))
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from common.exception.app_exception import AppApiException
|
|||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import ValidCode, BaseModelCredential
|
||||
from setting.models_provider.impl.aliyun_bai_lian_model_provider.model.embedding import AliyunBaiLianEmbedding
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AliyunBaiLianEmbeddingCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -21,21 +22,22 @@ class AliyunBaiLianEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['dashscope_api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model: AliyunBaiLianEmbedding = provider.get_model(model_type, model_name, model_credential)
|
||||
model.embed_query('你好')
|
||||
model.embed_query(_('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -16,10 +16,12 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class QwenModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'),
|
||||
_('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=1.0,
|
||||
_min=0.1,
|
||||
_max=1.9,
|
||||
|
|
@ -27,7 +29,8 @@ class QwenModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'),
|
||||
_('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -41,23 +44,26 @@ class QwenVLModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": "你好"}])])
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": _('Hello')}])])
|
||||
for chunk in res:
|
||||
print(chunk)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class BaiLianLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'),
|
||||
_('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -18,7 +20,8 @@ class BaiLianLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'),
|
||||
_('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -32,22 +35,25 @@ class BaiLianLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
model.invoke([HumanMessage(content='你好')])
|
||||
model.invoke([HumanMessage(content=_('Hello'))])
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
@ -55,7 +61,7 @@ class BaiLianLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
|
||||
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def get_model_params_setting_form(self, model_name):
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from common.exception.app_exception import AppApiException
|
|||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from setting.models_provider.impl.aliyun_bai_lian_model_provider.model.reranker import AliyunBaiLianReranker
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AliyunBaiLianRerankerCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -22,21 +23,24 @@ class AliyunBaiLianRerankerCredential(BaseForm, BaseModelCredential):
|
|||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
if not model_type == 'RERANKER':
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['dashscope_api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model: AliyunBaiLianReranker = provider.get_model(model_type, model_name, model_credential)
|
||||
model.compress_documents([Document(page_content='你好')], '你好')
|
||||
model.compress_documents([Document(page_content=_('Hello'))], _('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AliyunBaiLianSTTModelCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -15,12 +16,13 @@ class AliyunBaiLianSTTModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -30,7 +32,9 @@ class AliyunBaiLianSTTModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -6,21 +6,18 @@
|
|||
@date:2024/7/11 18:41
|
||||
@desc:
|
||||
"""
|
||||
import base64
|
||||
import os
|
||||
from typing import Dict
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
||||
from common import forms
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class QwenModelParams(BaseForm):
|
||||
size = forms.SingleSelect(
|
||||
TooltipLabel('图片尺寸', '指定生成图片的尺寸, 如: 1024x1024'),
|
||||
TooltipLabel(_('Image size'), _('Specify the size of the generated image, such as: 1024x1024')),
|
||||
required=True,
|
||||
default_value='1024*1024',
|
||||
option_list=[
|
||||
|
|
@ -32,27 +29,27 @@ class QwenModelParams(BaseForm):
|
|||
text_field='label',
|
||||
value_field='value')
|
||||
n = forms.SliderField(
|
||||
TooltipLabel('图片数量', '指定生成图片的数量'),
|
||||
TooltipLabel(_('Number of pictures'), _('Specify the number of generated images')),
|
||||
required=True, default_value=1,
|
||||
_min=1,
|
||||
_max=4,
|
||||
_step=1,
|
||||
precision=0)
|
||||
style = forms.SingleSelect(
|
||||
TooltipLabel('风格', '指定生成图片的风格'),
|
||||
TooltipLabel(_('Style'), _('Specify the style of generated images')),
|
||||
required=True,
|
||||
default_value='<auto>',
|
||||
option_list=[
|
||||
{'value': '<auto>', 'label': '默认值,由模型随机输出图像风格'},
|
||||
{'value': '<photography>', 'label': '摄影'},
|
||||
{'value': '<portrait>', 'label': '人像写真'},
|
||||
{'value': '<3d cartoon>', 'label': '3D卡通'},
|
||||
{'value': '<anime>', 'label': '动画'},
|
||||
{'value': '<oil painting>', 'label': '油画'},
|
||||
{'value': '<watercolor>', 'label': '水彩'},
|
||||
{'value': '<sketch>', 'label': '素描'},
|
||||
{'value': '<chinese painting>', 'label': '中国画'},
|
||||
{'value': '<flat illustration>', 'label': '扁平插画'},
|
||||
{'value': '<auto>', 'label': _('Default value, the image style is randomly output by the model')},
|
||||
{'value': '<photography>', 'label': _('photography')},
|
||||
{'value': '<portrait>', 'label': _('Portraits')},
|
||||
{'value': '<3d cartoon>', 'label': _('3D cartoon')},
|
||||
{'value': '<anime>', 'label': _('animation')},
|
||||
{'value': '<oil painting>', 'label': _('painting')},
|
||||
{'value': '<watercolor>', 'label': _('watercolor')},
|
||||
{'value': '<sketch>', 'label': _('sketch')},
|
||||
{'value': '<chinese painting>', 'label': _('Chinese painting')},
|
||||
{'value': '<flat illustration>', 'label': _('flat illustration')},
|
||||
],
|
||||
text_field='label',
|
||||
value_field='value'
|
||||
|
|
@ -65,11 +62,12 @@ class QwenTextToImageModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -80,7 +78,9 @@ class QwenTextToImageModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -6,35 +6,36 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AliyunBaiLianTTSModelGeneralParams(BaseForm):
|
||||
voice = forms.SingleSelect(
|
||||
TooltipLabel('音色', '中文音色可支持中英文混合场景'),
|
||||
TooltipLabel(_('timbre'), _('Chinese sounds can support mixed scenes of Chinese and English')),
|
||||
required=True, default_value='longxiaochun',
|
||||
text_field='value',
|
||||
value_field='value',
|
||||
option_list=[
|
||||
{'text': '龙小淳', 'value': 'longxiaochun'},
|
||||
{'text': '龙小夏', 'value': 'longxiaoxia'},
|
||||
{'text': '龙小诚', 'value': 'longxiaocheng'},
|
||||
{'text': '龙小白', 'value': 'longxiaobai'},
|
||||
{'text': '龙老铁', 'value': 'longlaotie'},
|
||||
{'text': '龙书', 'value': 'longshu'},
|
||||
{'text': '龙硕', 'value': 'longshuo'},
|
||||
{'text': '龙婧', 'value': 'longjing'},
|
||||
{'text': '龙妙', 'value': 'longmiao'},
|
||||
{'text': '龙悦', 'value': 'longyue'},
|
||||
{'text': '龙媛', 'value': 'longyuan'},
|
||||
{'text': '龙飞', 'value': 'longfei'},
|
||||
{'text': '龙杰力豆', 'value': 'longjielidou'},
|
||||
{'text': '龙彤', 'value': 'longtong'},
|
||||
{'text': '龙祥', 'value': 'longxiang'},
|
||||
{'text': _('Long Xiaochun'), 'value': 'longxiaochun'},
|
||||
{'text': _('Long Xiaoxia'), 'value': 'longxiaoxia'},
|
||||
{'text': _('Long Xiaochen'), 'value': 'longxiaocheng'},
|
||||
{'text': _('Long Xiaobai'), 'value': 'longxiaobai'},
|
||||
{'text': _('Long laotie'), 'value': 'longlaotie'},
|
||||
{'text': _('Long Shu'), 'value': 'longshu'},
|
||||
{'text': _('Long Shuo'), 'value': 'longshuo'},
|
||||
{'text': _('Long Jing'), 'value': 'longjing'},
|
||||
{'text': _('Long Miao'), 'value': 'longmiao'},
|
||||
{'text': _('Long Yue'), 'value': 'longyue'},
|
||||
{'text': _('Long Yuan'), 'value': 'longyuan'},
|
||||
{'text': _('Long Fei'), 'value': 'longfei'},
|
||||
{'text': _('Long Jielidou'), 'value': 'longjielidou'},
|
||||
{'text': _('Long Tong'), 'value': 'longtong'},
|
||||
{'text': _('Long Xiang'), 'value': 'longxiang'},
|
||||
{'text': 'Stella', 'value': 'loongstella'},
|
||||
{'text': 'Bella', 'value': 'loongbella'},
|
||||
])
|
||||
speech_rate = forms.SliderField(
|
||||
TooltipLabel('语速', '[0.5,2],默认为1,通常保留一位小数即可'),
|
||||
TooltipLabel(_('speaking speed'), _('[0.5,2], the default is 1, usually one decimal place is enough')),
|
||||
required=True, default_value=1,
|
||||
_min=0.5,
|
||||
_max=2,
|
||||
|
|
@ -49,12 +50,13 @@ class AliyunBaiLianTTSModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -64,7 +66,9 @@ class AliyunBaiLianTTSModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from langchain_core.messages import HumanMessage
|
|||
|
||||
from setting.models_provider.base_model_provider import MaxKBBaseModel
|
||||
from setting.models_provider.impl.base_tti import BaseTextToImage
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class QwenTextToImageModel(MaxKBBaseModel, BaseTextToImage):
|
||||
api_key: str
|
||||
|
|
@ -39,7 +39,7 @@ class QwenTextToImageModel(MaxKBBaseModel, BaseTextToImage):
|
|||
|
||||
def check_auth(self):
|
||||
chat = ChatTongyi(api_key=self.api_key, model_name='qwen-max')
|
||||
chat.invoke([HumanMessage([{"type": "text", "text": "你好"}])])
|
||||
chat.invoke([HumanMessage([{"type": "text", "text": _('Hello')}])])
|
||||
|
||||
def generate_image(self, prompt: str, negative_prompt: str = None):
|
||||
# api_base='https://dashscope.aliyuncs.com/compatible-mode/v1',
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from dashscope.audio.tts_v2 import *
|
|||
from common.util.common import _remove_empty_lines
|
||||
from setting.models_provider.base_model_provider import MaxKBBaseModel
|
||||
from setting.models_provider.impl.base_tts import BaseTextToSpeech
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class AliyunBaiLianTextToSpeech(MaxKBBaseModel, BaseTextToSpeech):
|
||||
api_key: str
|
||||
|
|
@ -33,7 +33,7 @@ class AliyunBaiLianTextToSpeech(MaxKBBaseModel, BaseTextToSpeech):
|
|||
)
|
||||
|
||||
def check_auth(self):
|
||||
self.text_to_speech('你好')
|
||||
self.text_to_speech(_('Hello'))
|
||||
|
||||
def text_to_speech(self, text):
|
||||
dashscope.api_key = self.api_key
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from setting.models_provider.impl.aws_bedrock_model_provider.credential.llm impo
|
|||
from setting.models_provider.impl.aws_bedrock_model_provider.model.embedding import BedrockEmbeddingModel
|
||||
from setting.models_provider.impl.aws_bedrock_model_provider.model.llm import BedrockModel
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
def _create_model_info(model_name, description, model_type, credential_class, model_class):
|
||||
return ModelInfo(
|
||||
|
|
@ -32,86 +32,92 @@ def _initialize_model_info():
|
|||
model_info_list = [
|
||||
_create_model_info(
|
||||
'anthropic.claude-v2:1',
|
||||
'Claude 2 的更新,采用双倍的上下文窗口,并在长文档和 RAG 上下文中提高可靠性、幻觉率和循证准确性。',
|
||||
_('An update to Claude 2 that doubles the context window and improves reliability, hallucination rates, and evidence-based accuracy in long documents and RAG contexts.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel
|
||||
),
|
||||
_create_model_info(
|
||||
'anthropic.claude-v2',
|
||||
'Anthropic 功能强大的模型,可处理各种任务,从复杂的对话和创意内容生成到详细的指令服从。',
|
||||
_('Anthropic is a powerful model that can handle a variety of tasks, from complex dialogue and creative content generation to detailed command obedience.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel
|
||||
),
|
||||
_create_model_info(
|
||||
'anthropic.claude-3-haiku-20240307-v1:0',
|
||||
'Claude 3 Haiku 是 Anthropic 最快速、最紧凑的模型,具有近乎即时的响应能力。该模型可以快速回答简单的查询和请求。客户将能够构建模仿人类交互的无缝人工智能体验。 Claude 3 Haiku 可以处理图像和返回文本输出,并且提供 200K 上下文窗口。',
|
||||
_('''
|
||||
The Claude 3 Haiku is Anthropic's fastest and most compact model, with near-instant responsiveness. The model can answer simple queries and requests quickly. Customers will be able to build seamless AI experiences that mimic human interactions. Claude 3 Haiku can process images and return text output, and provides 200K context windows.
|
||||
'''),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel
|
||||
),
|
||||
_create_model_info(
|
||||
'anthropic.claude-3-sonnet-20240229-v1:0',
|
||||
'Anthropic 推出的 Claude 3 Sonnet 模型在智能和速度之间取得理想的平衡,尤其是在处理企业工作负载方面。该模型提供最大的效用,同时价格低于竞争产品,并且其经过精心设计,是大规模部署人工智能的可靠选择。',
|
||||
_('''
|
||||
The Claude 3 Sonnet model from Anthropic strikes the ideal balance between intelligence and speed, especially when it comes to handling enterprise workloads. This model offers maximum utility while being priced lower than competing products, and it's been engineered to be a solid choice for deploying AI at scale.
|
||||
'''),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel
|
||||
),
|
||||
_create_model_info(
|
||||
'anthropic.claude-3-5-sonnet-20240620-v1:0',
|
||||
'Claude 3.5 Sonnet提高了智能的行业标准,在广泛的评估中超越了竞争对手的型号和Claude 3 Opus,具有我们中端型号的速度和成本效益。',
|
||||
_('The Claude 3.5 Sonnet raises the industry standard for intelligence, outperforming competing models and the Claude 3 Opus in extensive evaluations, with the speed and cost-effectiveness of our mid-range models.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel
|
||||
),
|
||||
_create_model_info(
|
||||
'anthropic.claude-instant-v1',
|
||||
'一种更快速、更实惠但仍然非常强大的模型,它可以处理一系列任务,包括随意对话、文本分析、摘要和文档问题回答。',
|
||||
_('A faster, more affordable but still very powerful model that can handle a range of tasks including casual conversation, text analysis, summarization and document question answering.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel
|
||||
),
|
||||
_create_model_info(
|
||||
'amazon.titan-text-premier-v1:0',
|
||||
'Titan Text Premier 是 Titan Text 系列中功能强大且先进的型号,旨在为各种企业应用程序提供卓越的性能。凭借其尖端功能,它提供了更高的准确性和出色的结果,使其成为寻求一流文本处理解决方案的组织的绝佳选择。',
|
||||
_('''
|
||||
Titan Text Premier is the most powerful and advanced model in the Titan Text series, designed to deliver exceptional performance for a variety of enterprise applications. With its cutting-edge features, it delivers greater accuracy and outstanding results, making it an excellent choice for organizations looking for a top-notch text processing solution.
|
||||
'''),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel
|
||||
),
|
||||
_create_model_info(
|
||||
'amazon.titan-text-lite-v1',
|
||||
'Amazon Titan Text Lite 是一种轻量级的高效模型,非常适合英语任务的微调,包括摘要和文案写作等,在这种场景下,客户需要更小、更经济高效且高度可定制的模型',
|
||||
_('Amazon Titan Text Lite is a lightweight, efficient model ideal for fine-tuning English-language tasks, including summarization and copywriting, where customers require smaller, more cost-effective, and highly customizable models.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel),
|
||||
_create_model_info(
|
||||
'amazon.titan-text-express-v1',
|
||||
'Amazon Titan Text Express 的上下文长度长达 8000 个令牌,因而非常适合各种高级常规语言任务,例如开放式文本生成和对话式聊天,以及检索增强生成(RAG)中的支持。在发布时,该模型针对英语进行了优化,但也支持其他语言。',
|
||||
_('Amazon Titan Text Express has context lengths of up to 8,000 tokens, making it ideal for a variety of high-level general language tasks, such as open-ended text generation and conversational chat, as well as support in retrieval-augmented generation (RAG). At launch, the model is optimized for English, but other languages are supported.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel),
|
||||
_create_model_info(
|
||||
'mistral.mistral-7b-instruct-v0:2',
|
||||
'7B 密集型转换器,可快速部署,易于定制。体积虽小,但功能强大,适用于各种用例。支持英语和代码,以及 32k 的上下文窗口。',
|
||||
_('7B dense converter for rapid deployment and easy customization. Small in size yet powerful in a variety of use cases. Supports English and code, as well as 32k context windows.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel),
|
||||
_create_model_info(
|
||||
'mistral.mistral-large-2402-v1:0',
|
||||
'先进的 Mistral AI 大型语言模型,能够处理任何语言任务,包括复杂的多语言推理、文本理解、转换和代码生成。',
|
||||
_('Advanced Mistral AI large-scale language model capable of handling any language task, including complex multilingual reasoning, text understanding, transformation, and code generation.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel),
|
||||
_create_model_info(
|
||||
'meta.llama3-70b-instruct-v1:0',
|
||||
'非常适合内容创作、会话式人工智能、语言理解、研发和企业应用',
|
||||
_('Ideal for content creation, conversational AI, language understanding, R&D, and enterprise applications'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel),
|
||||
_create_model_info(
|
||||
'meta.llama3-8b-instruct-v1:0',
|
||||
'非常适合有限的计算能力和资源、边缘设备和更快的训练时间。',
|
||||
_('Ideal for limited computing power and resources, edge devices, and faster training times.'),
|
||||
ModelTypeConst.LLM,
|
||||
BedrockLLMModelCredential,
|
||||
BedrockModel),
|
||||
|
|
@ -119,7 +125,7 @@ def _initialize_model_info():
|
|||
embedded_model_info_list = [
|
||||
_create_model_info(
|
||||
'amazon.titan-embed-text-v1',
|
||||
'Titan Embed Text 是 Amazon Titan Embed 系列中最大的嵌入模型,可以处理各种文本嵌入任务,如文本分类、文本相似度计算等。',
|
||||
_('Titan Embed Text is the largest embedding model in the Amazon Titan Embed series and can handle various text embedding tasks, such as text classification, text similarity calculation, etc.'),
|
||||
ModelTypeConst.EMBEDDING,
|
||||
BedrockEmbeddingCredential,
|
||||
BedrockEmbeddingModel
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from common.exception.app_exception import AppApiException
|
|||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from setting.models_provider.impl.aws_bedrock_model_provider.model.embedding import BedrockEmbeddingModel
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class BedrockEmbeddingCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -16,24 +17,24 @@ class BedrockEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
model_type_list = provider.get_model_type_list()
|
||||
if not any(mt.get('value') == model_type for mt in model_type_list):
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
return False
|
||||
|
||||
required_keys = ['region_name', 'access_key_id', 'secret_access_key']
|
||||
if not all(key in model_credential for key in required_keys):
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'以下字段为必填字段: {", ".join(required_keys)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('The following fields are required: {keys}').format(keys=", ".join(required_keys)))
|
||||
return False
|
||||
|
||||
try:
|
||||
model: BedrockEmbeddingModel = provider.get_model(model_type, model_name, model_credential)
|
||||
aa = model.embed_query('你好')
|
||||
aa = model.embed_query(_('Hello'))
|
||||
print(aa)
|
||||
except AppApiException:
|
||||
raise
|
||||
except Exception as e:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
from typing import Dict
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
|
@ -7,10 +6,12 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import ValidCode, BaseModelCredential
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class BedrockLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'),
|
||||
_('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -18,7 +19,8 @@ class BedrockLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'),
|
||||
_('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=1024,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -28,30 +30,33 @@ class BedrockLLMModelParams(BaseForm):
|
|||
|
||||
class BedrockLLMModelCredential(BaseForm, BaseModelCredential):
|
||||
|
||||
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(mt.get('value') == model_type for mt in model_type_list):
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
return False
|
||||
|
||||
required_keys = ['region_name', 'access_key_id', 'secret_access_key']
|
||||
if not all(key in model_credential for key in required_keys):
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'以下字段为必填字段: {", ".join(required_keys)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('The following fields are required: {keys}').format(
|
||||
keys=", ".join(required_keys)))
|
||||
return False
|
||||
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
model.invoke([HumanMessage(content='你好')])
|
||||
model.invoke([HumanMessage(content=_('Hello'))])
|
||||
except AppApiException:
|
||||
raise
|
||||
except Exception as e:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ from setting.models_provider.impl.azure_model_provider.model.stt import AzureOpe
|
|||
from setting.models_provider.impl.azure_model_provider.model.tti import AzureOpenAITextToImage
|
||||
from setting.models_provider.impl.azure_model_provider.model.tts import AzureOpenAITextToSpeech
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
base_azure_llm_model_credential = AzureLLMModelCredential()
|
||||
base_azure_embedding_model_credential = AzureOpenAIEmbeddingCredential()
|
||||
|
|
@ -33,7 +34,7 @@ base_azure_tts_model_credential = AzureOpenAITTSModelCredential()
|
|||
base_azure_stt_model_credential = AzureOpenAISTTModelCredential()
|
||||
|
||||
default_model_info = [
|
||||
ModelInfo('Azure OpenAI', '具体的基础模型由部署名决定', ModelTypeConst.LLM,
|
||||
ModelInfo('Azure OpenAI', '', ModelTypeConst.LLM,
|
||||
base_azure_llm_model_credential, AzureChatModel, api_version='2024-02-15-preview'
|
||||
),
|
||||
ModelInfo('gpt-4', '', ModelTypeConst.LLM,
|
||||
|
|
@ -48,7 +49,7 @@ default_model_info = [
|
|||
]
|
||||
|
||||
embedding_model_info = [
|
||||
ModelInfo('text-embedding-3-large', '具体的基础模型由部署名决定', ModelTypeConst.EMBEDDING,
|
||||
ModelInfo('text-embedding-3-large', '', ModelTypeConst.EMBEDDING,
|
||||
base_azure_embedding_model_credential, AzureOpenAIEmbeddingModel, api_version='2023-05-15'
|
||||
),
|
||||
ModelInfo('text-embedding-3-small', '', ModelTypeConst.EMBEDDING,
|
||||
|
|
|
|||
|
|
@ -8,13 +8,11 @@
|
|||
"""
|
||||
from typing import Dict
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
||||
from common import forms
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AzureOpenAIEmbeddingCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -23,22 +21,24 @@ class AzureOpenAIEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key', 'api_version']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential)
|
||||
model.embed_query('你好')
|
||||
model.embed_query(_('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, '校验失败,请检查参数是否正确')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct'))
|
||||
else:
|
||||
return False
|
||||
|
||||
|
|
@ -47,9 +47,8 @@ class AzureOpenAIEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
|
||||
|
||||
api_version = forms.TextInputField("API 版本 (api_version)", required=True)
|
||||
api_version = forms.TextInputField("Api Version", required=True)
|
||||
|
||||
api_base = forms.TextInputField('API 域名 (azure_endpoint)', required=True)
|
||||
|
||||
api_key = forms.PasswordInputField("API Key (api_key)", required=True)
|
||||
api_base = forms.TextInputField('Azure Endpoint', required=True)
|
||||
|
||||
api_key = forms.PasswordInputField("API Key", required=True)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,12 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AzureOpenAIImageModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'),
|
||||
_('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -19,7 +22,8 @@ class AzureOpenAIImageModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'),
|
||||
_('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -27,34 +31,36 @@ class AzureOpenAIImageModelParams(BaseForm):
|
|||
precision=0)
|
||||
|
||||
|
||||
|
||||
class AzureOpenAIImageModelCredential(BaseForm, BaseModelCredential):
|
||||
api_version = forms.TextInputField("API 版本 (api_version)", required=True)
|
||||
api_base = forms.TextInputField('API 域名 (azure_endpoint)', required=True)
|
||||
api_key = forms.PasswordInputField("API Key (api_key)", required=True)
|
||||
api_version = forms.TextInputField("API Version", required=True)
|
||||
api_base = forms.TextInputField('Azure Endpoint', required=True)
|
||||
api_key = forms.PasswordInputField("API Key", required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key', 'api_version']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": "你好"}])])
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": _('Hello')}])])
|
||||
for chunk in res:
|
||||
print(chunk)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AzureLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'),
|
||||
_('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -25,7 +27,8 @@ class AzureLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'),
|
||||
_('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -39,22 +42,23 @@ class AzureLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key', 'deployment_name', 'api_version']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
model.invoke([HumanMessage(content='你好')])
|
||||
model.invoke([HumanMessage(content=_('Hello'))])
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, '校验失败,请检查参数是否正确')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct'))
|
||||
else:
|
||||
return False
|
||||
|
||||
|
|
@ -63,13 +67,13 @@ class AzureLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
|
||||
|
||||
api_version = forms.TextInputField("API 版本 (api_version)", required=True)
|
||||
api_version = forms.TextInputField("API Version", required=True)
|
||||
|
||||
api_base = forms.TextInputField('API 域名 (azure_endpoint)', required=True)
|
||||
api_base = forms.TextInputField('Azure Endpoint', required=True)
|
||||
|
||||
api_key = forms.PasswordInputField("API Key (api_key)", required=True)
|
||||
api_key = forms.PasswordInputField("API Key", required=True)
|
||||
|
||||
deployment_name = forms.TextInputField("部署名 (deployment_name)", required=True)
|
||||
deployment_name = forms.TextInputField("Deployment name", required=True)
|
||||
|
||||
def get_model_params_setting_form(self, model_name):
|
||||
return AzureLLMModelParams()
|
||||
|
|
|
|||
|
|
@ -5,23 +5,24 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AzureOpenAISTTModelCredential(BaseForm, BaseModelCredential):
|
||||
api_version = forms.TextInputField("API 版本 (api_version)", required=True)
|
||||
api_base = forms.TextInputField('API 域名 (azure_endpoint)', required=True)
|
||||
api_key = forms.PasswordInputField("API Key (api_key)", required=True)
|
||||
api_version = forms.TextInputField("API Version", required=True)
|
||||
api_base = forms.TextInputField('Azure Endpoint', required=True)
|
||||
api_key = forms.PasswordInputField("API Key", required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key', 'api_version']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -31,7 +32,7 @@ class AzureOpenAISTTModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -1,19 +1,16 @@
|
|||
# coding=utf-8
|
||||
import base64
|
||||
import os
|
||||
from typing import Dict
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
||||
from common import forms
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AzureOpenAITTIModelParams(BaseForm):
|
||||
size = forms.SingleSelect(
|
||||
TooltipLabel('图片尺寸', '指定生成图片的尺寸, 如: 1024x1024'),
|
||||
TooltipLabel(_('Image size'), _('Specify the size of the generated image, such as: 1024x1024')),
|
||||
required=True,
|
||||
default_value='1024x1024',
|
||||
option_list=[
|
||||
|
|
@ -26,7 +23,7 @@ class AzureOpenAITTIModelParams(BaseForm):
|
|||
)
|
||||
|
||||
quality = forms.SingleSelect(
|
||||
TooltipLabel('图片质量', ''),
|
||||
TooltipLabel(_('Picture quality'), ''),
|
||||
required=True,
|
||||
default_value='standard',
|
||||
option_list=[
|
||||
|
|
@ -38,7 +35,7 @@ class AzureOpenAITTIModelParams(BaseForm):
|
|||
)
|
||||
|
||||
n = forms.SliderField(
|
||||
TooltipLabel('图片数量', '指定生成图片的数量'),
|
||||
TooltipLabel(_('Number of pictures'), _('Specify the number of generated images')),
|
||||
required=True, default_value=1,
|
||||
_min=1,
|
||||
_max=10,
|
||||
|
|
@ -47,20 +44,20 @@ class AzureOpenAITTIModelParams(BaseForm):
|
|||
|
||||
|
||||
class AzureOpenAITextToImageModelCredential(BaseForm, BaseModelCredential):
|
||||
api_version = forms.TextInputField("API 版本 (api_version)", required=True)
|
||||
api_base = forms.TextInputField('API 域名 (azure_endpoint)', required=True)
|
||||
api_key = forms.PasswordInputField("API Key (api_key)", required=True)
|
||||
api_version = forms.TextInputField("API Version", required=True)
|
||||
api_base = forms.TextInputField('Azure Endpoint', required=True)
|
||||
api_key = forms.PasswordInputField("API Key", required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key', 'api_version']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -71,7 +68,7 @@ class AzureOpenAITextToImageModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class AzureOpenAITTSModelGeneralParams(BaseForm):
|
||||
# alloy, echo, fable, onyx, nova, shimmer
|
||||
voice = forms.SingleSelect(
|
||||
TooltipLabel('Voice', '尝试不同的声音(合金、回声、寓言、缟玛瑙、新星和闪光),找到一种适合您所需的音调和听众的声音。当前的语音针对英语进行了优化。'),
|
||||
TooltipLabel('Voice', _('Try out the different sounds (Alloy, Echo, Fable, Onyx, Nova, and Sparkle) to find one that suits your desired tone and audience. The current voiceover is optimized for English.')),
|
||||
required=True, default_value='alloy',
|
||||
text_field='value',
|
||||
value_field='value',
|
||||
|
|
@ -24,20 +25,20 @@ class AzureOpenAITTSModelGeneralParams(BaseForm):
|
|||
|
||||
|
||||
class AzureOpenAITTSModelCredential(BaseForm, BaseModelCredential):
|
||||
api_version = forms.TextInputField("API 版本 (api_version)", required=True)
|
||||
api_base = forms.TextInputField('API 域名 (azure_endpoint)', required=True)
|
||||
api_key = forms.PasswordInputField("API Key (api_key)", required=True)
|
||||
api_version = forms.TextInputField("API Version", required=True)
|
||||
api_base = forms.TextInputField('Azure Endpoint', required=True)
|
||||
api_key = forms.PasswordInputField("API Key", required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key', 'api_version']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -47,7 +48,7 @@ class AzureOpenAITTSModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class DeepSeekLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'),
|
||||
_('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -25,7 +27,8 @@ class DeepSeekLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'),
|
||||
_('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -39,22 +42,25 @@ class DeepSeekLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
model.invoke([HumanMessage(content='你好')])
|
||||
model.invoke([HumanMessage(content=_('Hello'))])
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value,
|
||||
_('Verification failed, please check whether the parameters are correct: {error}').format(
|
||||
error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ from setting.models_provider.base_model_provider import IModelProvider, ModelPro
|
|||
from setting.models_provider.impl.deepseek_model_provider.credential.llm import DeepSeekLLMModelCredential
|
||||
from setting.models_provider.impl.deepseek_model_provider.model.llm import DeepSeekChatModel
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
deepseek_llm_model_credential = DeepSeekLLMModelCredential()
|
||||
|
||||
deepseek_chat = ModelInfo('deepseek-chat', '擅长通用对话任务,支持 32K 上下文', ModelTypeConst.LLM,
|
||||
deepseek_chat = ModelInfo('deepseek-chat', _('Good at common conversational tasks, supports 32K contexts'), ModelTypeConst.LLM,
|
||||
deepseek_llm_model_credential, DeepSeekChatModel
|
||||
)
|
||||
|
||||
deepseek_coder = ModelInfo('deepseek-coder', '擅长处理编程任务,支持 16K 上下文', ModelTypeConst.LLM,
|
||||
deepseek_coder = ModelInfo('deepseek-coder', _('Good at handling programming tasks, supports 16K contexts'), ModelTypeConst.LLM,
|
||||
deepseek_llm_model_credential,
|
||||
DeepSeekChatModel)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,29 +12,29 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class GeminiEmbeddingCredential(BaseForm, BaseModelCredential):
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=True):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential)
|
||||
model.embed_query('你好')
|
||||
model.embed_query(_('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
# coding=utf-8
|
||||
import base64
|
||||
import os
|
||||
|
||||
from typing import Dict
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
|
@ -9,9 +8,9 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
class GeminiImageModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -19,7 +18,7 @@ class GeminiImageModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -35,24 +34,24 @@ class GeminiImageModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": "你好"}])])
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": _('Hello')}])])
|
||||
for chunk in res:
|
||||
print(chunk)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class GeminiLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -25,7 +25,7 @@ class GeminiLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -39,23 +39,23 @@ class GeminiLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.invoke([HumanMessage(content='你好')])
|
||||
res = model.invoke([HumanMessage(content=_('Hello'))])
|
||||
print(res)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class GeminiSTTModelCredential(BaseForm, BaseModelCredential):
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
|
@ -14,12 +14,12 @@ class GeminiSTTModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -29,7 +29,7 @@ class GeminiSTTModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ from setting.models_provider.impl.gemini_model_provider.model.image import Gemin
|
|||
from setting.models_provider.impl.gemini_model_provider.model.llm import GeminiChatModel
|
||||
from setting.models_provider.impl.gemini_model_provider.model.stt import GeminiSpeechToText
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
gemini_llm_model_credential = GeminiLLMModelCredential()
|
||||
gemini_image_model_credential = GeminiImageModelCredential()
|
||||
|
|
@ -27,33 +29,33 @@ gemini_stt_model_credential = GeminiSTTModelCredential()
|
|||
gemini_embedding_model_credential = GeminiEmbeddingCredential()
|
||||
|
||||
model_info_list = [
|
||||
ModelInfo('gemini-1.0-pro', '最新的Gemini 1.0 Pro模型,随Google更新而更新',
|
||||
ModelInfo('gemini-1.0-pro', _('Latest Gemini 1.0 Pro model, updated with Google update'),
|
||||
ModelTypeConst.LLM,
|
||||
gemini_llm_model_credential,
|
||||
GeminiChatModel),
|
||||
ModelInfo('gemini-1.0-pro-vision', '最新的Gemini 1.0 Pro Vision模型,随Google更新而更新',
|
||||
ModelInfo('gemini-1.0-pro-vision', _('Latest Gemini 1.0 Pro Vision model, updated with Google update'),
|
||||
ModelTypeConst.LLM,
|
||||
gemini_llm_model_credential,
|
||||
GeminiChatModel),
|
||||
]
|
||||
|
||||
model_image_info_list = [
|
||||
ModelInfo('gemini-1.5-flash', '最新的Gemini 1.5 Flash模型,随Google更新而更新',
|
||||
ModelInfo('gemini-1.5-flash', _('Latest Gemini 1.5 Flash model, updated with Google updates'),
|
||||
ModelTypeConst.IMAGE,
|
||||
gemini_image_model_credential,
|
||||
GeminiImage),
|
||||
ModelInfo('gemini-1.5-pro', '最新的Gemini 1.5 Flash模型,随Google更新而更新',
|
||||
ModelInfo('gemini-1.5-pro', _('Latest Gemini 1.5 Flash model, updated with Google updates'),
|
||||
ModelTypeConst.IMAGE,
|
||||
gemini_image_model_credential,
|
||||
GeminiImage),
|
||||
]
|
||||
|
||||
model_stt_info_list = [
|
||||
ModelInfo('gemini-1.5-flash', '最新的Gemini 1.5 Flash模型,随Google更新而更新',
|
||||
ModelInfo('gemini-1.5-flash', _('Latest Gemini 1.5 Flash model, updated with Google updates'),
|
||||
ModelTypeConst.STT,
|
||||
gemini_stt_model_credential,
|
||||
GeminiSpeechToText),
|
||||
ModelInfo('gemini-1.5-pro', '最新的Gemini 1.5 Flash模型,随Google更新而更新',
|
||||
ModelInfo('gemini-1.5-pro', _('Latest Gemini 1.5 Flash model, updated with Google updates'),
|
||||
ModelTypeConst.STT,
|
||||
gemini_stt_model_credential,
|
||||
GeminiSpeechToText),
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
import asyncio
|
||||
import io
|
||||
|
||||
from typing import Dict
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||
from openai import OpenAI
|
||||
|
||||
from common.config.tokenizer_manage_config import TokenizerManage
|
||||
from setting.models_provider.base_model_provider import MaxKBBaseModel
|
||||
from setting.models_provider.impl.base_stt import BaseSpeechToText
|
||||
import google.generativeai as genai
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
def custom_get_token_ids(text: str):
|
||||
|
|
@ -43,7 +41,7 @@ class GeminiSpeechToText(MaxKBBaseModel, BaseSpeechToText):
|
|||
model=self.model,
|
||||
google_api_key=self.api_key
|
||||
)
|
||||
response_list = client.invoke('你好')
|
||||
response_list = client.invoke(_('Hello'))
|
||||
# print(response_list)
|
||||
|
||||
def speech_to_text(self, audio_file):
|
||||
|
|
@ -53,7 +51,7 @@ class GeminiSpeechToText(MaxKBBaseModel, BaseSpeechToText):
|
|||
)
|
||||
audio_data = audio_file.read()
|
||||
msg = HumanMessage(content=[
|
||||
{'type': 'text', 'text': '把音频转成文字'},
|
||||
{'type': 'text', 'text': _('convert audio to text')},
|
||||
{"type": "media", 'mime_type': 'audio/mp3', "data": audio_data}
|
||||
])
|
||||
res = client.invoke([msg])
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class KimiLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.3,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -25,7 +26,7 @@ class KimiLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=1024,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -39,22 +40,22 @@ class KimiLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
model.invoke([HumanMessage(content='你好')])
|
||||
model.invoke([HumanMessage(content=_('Hello'))])
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
@ -62,7 +63,7 @@ class KimiLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
|
||||
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def get_model_params_setting_form(self, model_name):
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from common.exception.app_exception import AppApiException
|
|||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from setting.models_provider.impl.local_model_provider.model.embedding import LocalEmbedding
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class LocalEmbeddingCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -20,21 +21,21 @@ class LocalEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
if not model_type == 'EMBEDDING':
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['cache_folder']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model: LocalEmbedding = provider.get_model(model_type, model_name, model_credential)
|
||||
model.embed_query('你好')
|
||||
model.embed_query(_('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
@ -42,4 +43,4 @@ class LocalEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return model
|
||||
|
||||
cache_folder = forms.TextInputField('模型目录', required=True)
|
||||
cache_folder = forms.TextInputField(_('Model catalog'), required=True)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from common.exception.app_exception import AppApiException
|
|||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from setting.models_provider.impl.local_model_provider.model.reranker import LocalBaseReranker
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class LocalRerankerCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -22,21 +23,21 @@ class LocalRerankerCredential(BaseForm, BaseModelCredential):
|
|||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
if not model_type == 'RERANKER':
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['cache_dir']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model: LocalBaseReranker = provider.get_model(model_type, model_name, model_credential)
|
||||
model.compress_documents([Document(page_content='你好')], '你好')
|
||||
model.compress_documents([Document(page_content=_('Hello'))], _('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
@ -44,4 +45,4 @@ class LocalRerankerCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return model
|
||||
|
||||
cache_dir = forms.TextInputField('模型目录', required=True)
|
||||
cache_dir = forms.TextInputField(_('Model catalog'), required=True)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,7 @@
|
|||
@desc:
|
||||
"""
|
||||
import os
|
||||
from typing import Dict
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.util.file_util import get_file_content
|
||||
from setting.models_provider.base_model_provider import ModelProvideInfo, ModelTypeConst, ModelInfo, IModelProvider, \
|
||||
ModelInfoManage
|
||||
|
|
@ -20,6 +16,7 @@ from setting.models_provider.impl.local_model_provider.credential.reranker impor
|
|||
from setting.models_provider.impl.local_model_provider.model.embedding import LocalEmbedding
|
||||
from setting.models_provider.impl.local_model_provider.model.reranker import LocalReranker
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
embedding_text2vec_base_chinese = ModelInfo('shibing624/text2vec-base-chinese', '', ModelTypeConst.EMBEDDING,
|
||||
LocalEmbeddingCredential(), LocalEmbedding)
|
||||
|
|
@ -39,6 +36,6 @@ class LocalModelProvider(IModelProvider):
|
|||
return model_info_manage
|
||||
|
||||
def get_model_provide_info(self):
|
||||
return ModelProvideInfo(provider='model_local_provider', name='本地模型', icon=get_file_content(
|
||||
return ModelProvideInfo(provider='model_local_provider', name=_('local model'), icon=get_file_content(
|
||||
os.path.join(PROJECT_DIR, "apps", "setting", 'models_provider', 'impl', 'local_model_provider', 'icon',
|
||||
'local_icon_svg')))
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from common.exception.app_exception import AppApiException
|
|||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from setting.models_provider.impl.local_model_provider.model.embedding import LocalEmbedding
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class OllamaEmbeddingModelCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -20,17 +21,17 @@ class OllamaEmbeddingModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
try:
|
||||
model_list = provider.get_base_model_list(model_credential.get('api_base'))
|
||||
except Exception as e:
|
||||
raise AppApiException(ValidCode.valid_error.value, "API 域名无效")
|
||||
raise AppApiException(ValidCode.valid_error.value, _('API domain name is invalid'))
|
||||
exist = [model for model in (model_list.get('models') if model_list.get('models') is not None else []) if
|
||||
model.get('model') == model_name or model.get('model').replace(":latest", "") == model_name]
|
||||
if len(exist) == 0:
|
||||
raise AppApiException(ValidCode.model_not_fount, "模型不存在,请先下载模型")
|
||||
raise AppApiException(ValidCode.model_not_fount, _('The model does not exist, please download the model first'))
|
||||
model: LocalEmbedding = provider.get_model(model_type, model_name, model_credential)
|
||||
model.embed_query('你好')
|
||||
model.embed_query(_('Hello'))
|
||||
return True
|
||||
|
||||
def encryption_dict(self, model_info: Dict[str, object]):
|
||||
|
|
@ -39,7 +40,7 @@ class OllamaEmbeddingModelCredential(BaseForm, BaseModelCredential):
|
|||
def build_model(self, model_info: Dict[str, object]):
|
||||
for key in ['model']:
|
||||
if key not in model_info:
|
||||
raise AppApiException(500, f'{key} 字段为必填字段')
|
||||
raise AppApiException(500, _('{key} is required').format(key=key))
|
||||
return self
|
||||
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
# coding=utf-8
|
||||
import base64
|
||||
import os
|
||||
from typing import Dict
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
||||
from common import forms
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class OllamaImageModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -19,7 +16,7 @@ class OllamaImageModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -29,22 +26,22 @@ class OllamaImageModelParams(BaseForm):
|
|||
|
||||
|
||||
class OllamaImageModelCredential(BaseForm, BaseModelCredential):
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
try:
|
||||
model_list = provider.get_base_model_list(model_credential.get('api_base'))
|
||||
except Exception as e:
|
||||
raise AppApiException(ValidCode.valid_error.value, "API 域名无效")
|
||||
raise AppApiException(ValidCode.valid_error.value, _('API domain name is invalid'))
|
||||
exist = [model for model in (model_list.get('models') if model_list.get('models') is not None else []) if
|
||||
model.get('model') == model_name or model.get('model').replace(":latest", "") == model_name]
|
||||
if len(exist) == 0:
|
||||
raise AppApiException(ValidCode.model_not_fount, "模型不存在,请先下载模型")
|
||||
raise AppApiException(ValidCode.model_not_fount, _('The model does not exist, please download the model first'))
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,11 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class OllamaLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.3,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -23,7 +24,7 @@ class OllamaLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=1024,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -36,15 +37,15 @@ class OllamaLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
try:
|
||||
model_list = provider.get_base_model_list(model_credential.get('api_base'))
|
||||
except Exception as e:
|
||||
raise AppApiException(ValidCode.valid_error.value, "API 域名无效")
|
||||
raise AppApiException(ValidCode.valid_error.value, _('API domain name is invalid'))
|
||||
exist = [model for model in (model_list.get('models') if model_list.get('models') is not None else []) if
|
||||
model.get('model') == model_name or model.get('model').replace(":latest", "") == model_name]
|
||||
if len(exist) == 0:
|
||||
raise AppApiException(ValidCode.model_not_fount, "模型不存在,请先下载模型")
|
||||
raise AppApiException(ValidCode.model_not_fount, _('The model does not exist, please download the model first'))
|
||||
return True
|
||||
|
||||
def encryption_dict(self, model_info: Dict[str, object]):
|
||||
|
|
@ -53,11 +54,11 @@ class OllamaLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
def build_model(self, model_info: Dict[str, object]):
|
||||
for key in ['api_key', 'model']:
|
||||
if key not in model_info:
|
||||
raise AppApiException(500, f'{key} 字段为必填字段')
|
||||
raise AppApiException(500, _('{key} is required').format(key=key))
|
||||
self.api_key = model_info.get('api_key')
|
||||
return self
|
||||
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def get_model_params_setting_form(self, model_name):
|
||||
|
|
|
|||
|
|
@ -12,11 +12,6 @@ from typing import Dict, Iterator
|
|||
from urllib.parse import urlparse, ParseResult
|
||||
|
||||
import requests
|
||||
from langchain.chat_models.base import BaseChatModel
|
||||
|
||||
from common import forms
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from common.util.file_util import get_file_content
|
||||
from setting.models_provider.base_model_provider import IModelProvider, ModelProvideInfo, ModelInfo, ModelTypeConst, \
|
||||
BaseModelCredential, DownModelChunk, DownModelChunkStatus, ValidCode, ModelInfoManage
|
||||
|
|
@ -27,6 +22,7 @@ from setting.models_provider.impl.ollama_model_provider.model.embedding import O
|
|||
from setting.models_provider.impl.ollama_model_provider.model.image import OllamaImage
|
||||
from setting.models_provider.impl.ollama_model_provider.model.llm import OllamaChatModel
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
""
|
||||
|
||||
|
|
@ -34,60 +30,73 @@ ollama_llm_model_credential = OllamaLLMModelCredential()
|
|||
model_info_list = [
|
||||
ModelInfo(
|
||||
'llama2',
|
||||
'Llama 2 是一组经过预训练和微调的生成文本模型,其规模从 70 亿到 700 亿个不等。这是 7B 预训练模型的存储库。其他模型的链接可以在底部的索引中找到。',
|
||||
_('Llama 2 is a set of pretrained and fine-tuned generative text models ranging in size from 7 billion to 70 billion. This is a repository of 7B pretrained models. Links to other models can be found in the index at the bottom.'),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'llama2:13b',
|
||||
'Llama 2 是一组经过预训练和微调的生成文本模型,其规模从 70 亿到 700 亿个不等。这是 13B 预训练模型的存储库。其他模型的链接可以在底部的索引中找到。',
|
||||
_('Llama 2 is a set of pretrained and fine-tuned generative text models ranging in size from 7 billion to 70 billion. This is a repository of 13B pretrained models. Links to other models can be found in the index at the bottom.'),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'llama2:70b',
|
||||
'Llama 2 是一组经过预训练和微调的生成文本模型,其规模从 70 亿到 700 亿个不等。这是 70B 预训练模型的存储库。其他模型的链接可以在底部的索引中找到。',
|
||||
_('Llama 2 is a set of pretrained and fine-tuned generative text models ranging in size from 7 billion to 70 billion. This is a repository of 70B pretrained models. Links to other models can be found in the index at the bottom.'),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'llama2-chinese:13b',
|
||||
'由于Llama2本身的中文对齐较弱,我们采用中文指令集,对meta-llama/Llama-2-13b-chat-hf进行LoRA微调,使其具备较强的中文对话能力。',
|
||||
_('Since the Chinese alignment of Llama2 itself is weak, we use the Chinese instruction set to fine-tune meta-llama/Llama-2-13b-chat-hf with LoRA so that it has strong Chinese conversation capabilities.'),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'llama3:8b',
|
||||
'Meta Llama 3:迄今为止最有能力的公开产品LLM。80亿参数。',
|
||||
_('Meta Llama 3: The most capable public product LLM to date. 8 billion parameters.'),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'llama3:70b',
|
||||
'Meta Llama 3:迄今为止最有能力的公开产品LLM。700亿参数。',
|
||||
_('Meta Llama 3: The most capable public product LLM to date. 70 billion parameters.'),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'qwen:0.5b',
|
||||
'qwen 1.5 0.5b 相较于以往版本,模型与人类偏好的对齐程度以及多语言处理能力上有显著增强。所有规模的模型都支持32768个tokens的上下文长度。5亿参数。',
|
||||
_('''
|
||||
Compared with previous versions, qwen 1.5 0.5b has significantly enhanced the model's alignment with human preferences and its multi-language processing capabilities. Models of all sizes support a context length of 32768 tokens. 500 million parameters.
|
||||
'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'qwen:1.8b',
|
||||
'qwen 1.5 1.8b 相较于以往版本,模型与人类偏好的对齐程度以及多语言处理能力上有显著增强。所有规模的模型都支持32768个tokens的上下文长度。18亿参数。',
|
||||
_('''
|
||||
|
||||
Compared with previous versions, qwen 1.5 1.8b has significantly enhanced the model's alignment with human preferences and its multi-language processing capabilities. Models of all sizes support a context length of 32768 tokens. 1.8 billion parameters.
|
||||
'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'qwen:4b',
|
||||
'qwen 1.5 4b 相较于以往版本,模型与人类偏好的对齐程度以及多语言处理能力上有显著增强。所有规模的模型都支持32768个tokens的上下文长度。40亿参数。',
|
||||
_('''
|
||||
|
||||
Compared with previous versions, qwen 1.5 4b has significantly enhanced the model's alignment with human preferences and its multi-language processing capabilities. Models of all sizes support a context length of 32768 tokens. 4 billion parameters.
|
||||
'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
|
||||
ModelInfo(
|
||||
'qwen:7b',
|
||||
'qwen 1.5 7b 相较于以往版本,模型与人类偏好的对齐程度以及多语1言处理能力上有显著增强。所有规模的模型都支持32768个tokens的上下文长度。70亿参数。',
|
||||
_('''
|
||||
Compared with previous versions, qwen 1.5 7b has significantly enhanced the model's alignment with human preferences and its multi-language processing capabilities. Models of all sizes support a context length of 32768 tokens. 7 billion parameters.
|
||||
'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'qwen:14b',
|
||||
'qwen 1.5 14b 相较于以往版本,模型与人类偏好的对齐程度以及多语言处理能力上有显著增强。所有规模的模型都支持32768个tokens的上下文长度。140亿参数。',
|
||||
_('''Compared with previous versions, qwen 1.5 14b has significantly enhanced the model's alignment with human preferences and its multi-language processing capabilities. Models of all sizes support a context length of 32768 tokens. 14 billion parameters.'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'qwen:32b',
|
||||
'qwen 1.5 32b 相较于以往版本,模型与人类偏好的对齐程度以及多语言处理能力上有显著增强。所有规模的模型都支持32768个tokens的上下文长度。320亿参数。',
|
||||
_('''Compared with previous versions, qwen 1.5 32b has significantly enhanced the model's alignment with human preferences and its multi-language processing capabilities. Models of all sizes support a context length of 32768 tokens. 32 billion parameters.'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'qwen:72b',
|
||||
'qwen 1.5 72b 相较于以往版本,模型与人类偏好的对齐程度以及多语言处理能力上有显著增强。所有规模的模型都支持32768个tokens的上下文长度。720亿参数。',
|
||||
_('''
|
||||
Compared with previous versions, qwen 1.5 72b has significantly enhanced the model's alignment with human preferences and its multi-language processing capabilities. Models of all sizes support a context length of 32768 tokens. 72 billion parameters.'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'qwen:110b',
|
||||
'qwen 1.5 110b 相较于以往版本,模型与人类偏好的对齐程度以及多语言处理能力上有显著增强。所有规模的模型都支持32768个tokens的上下文长度。1100亿参数。',
|
||||
_('''
|
||||
Compared with previous versions, qwen 1.5 110b has significantly enhanced the model's alignment with human preferences and its multi-language processing capabilities. Models of all sizes support a context length of 32768 tokens. 110 billion parameters.
|
||||
'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'qwen2:72b-instruct',
|
||||
|
|
@ -131,7 +140,9 @@ model_info_list = [
|
|||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
ModelInfo(
|
||||
'phi3',
|
||||
'Phi-3 Mini是Microsoft的3.8B参数,轻量级,最先进的开放模型。',
|
||||
_('''
|
||||
Phi-3 Mini is Microsoft's 3.8B parameter, lightweight, state-of-the-art open model.
|
||||
'''),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel),
|
||||
]
|
||||
ollama_embedding_model_credential = OllamaEmbeddingModelCredential()
|
||||
|
|
@ -139,7 +150,7 @@ ollama_image_model_credential = OllamaImageModelCredential()
|
|||
embedding_model_info = [
|
||||
ModelInfo(
|
||||
'nomic-embed-text',
|
||||
'一个具有大令牌上下文窗口的高性能开放嵌入模型。',
|
||||
_('A high-performance open embedding model with a large token context window.'),
|
||||
ModelTypeConst.EMBEDDING, ollama_embedding_model_credential, OllamaEmbedding),
|
||||
]
|
||||
|
||||
|
|
@ -164,11 +175,11 @@ model_info_manage = (
|
|||
.append_model_info_list(embedding_model_info)
|
||||
.append_default_model_info(ModelInfo(
|
||||
'phi3',
|
||||
'Phi-3 Mini是Microsoft的3.8B参数,轻量级,最先进的开放模型。',
|
||||
_('Phi-3 Mini is Microsoft\'s 3.8B parameter, lightweight, state-of-the-art open model.'),
|
||||
ModelTypeConst.LLM, ollama_llm_model_credential, OllamaChatModel))
|
||||
.append_default_model_info(ModelInfo(
|
||||
'nomic-embed-text',
|
||||
'一个具有大令牌上下文窗口的高性能开放嵌入模型。',
|
||||
_('A high-performance open embedding model with a large token context window.'),
|
||||
ModelTypeConst.EMBEDDING, ollama_embedding_model_credential, OllamaEmbedding), )
|
||||
.append_model_info_list(image_model_info)
|
||||
.append_default_model_info(image_model_info[0])
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class OpenAIEmbeddingCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -19,22 +20,22 @@ class OpenAIEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=True):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential)
|
||||
model.embed_query('你好')
|
||||
model.embed_query(_('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
@ -42,5 +43,5 @@ class OpenAIEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
|
||||
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class OpenAIImageModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -19,7 +20,7 @@ class OpenAIImageModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -29,31 +30,31 @@ class OpenAIImageModelParams(BaseForm):
|
|||
|
||||
|
||||
class OpenAIImageModelCredential(BaseForm, BaseModelCredential):
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": "你好"}])])
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": _('Hello')}])])
|
||||
for chunk in res:
|
||||
print(chunk)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class OpenAILLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -25,7 +26,7 @@ class OpenAILLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -39,23 +40,23 @@ class OpenAILLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
model.invoke([HumanMessage(content='你好')])
|
||||
model.invoke([HumanMessage(content=_('Hello'))])
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
@ -63,7 +64,7 @@ class OpenAILLMModelCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
|
||||
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def get_model_params_setting_form(self, model_name):
|
||||
|
|
|
|||
|
|
@ -5,22 +5,22 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class OpenAISTTModelCredential(BaseForm, BaseModelCredential):
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -30,7 +30,7 @@ class OpenAISTTModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class OpenAITTIModelParams(BaseForm):
|
||||
size = forms.SingleSelect(
|
||||
TooltipLabel('图片尺寸', '图像生成端点允许您根据文本提示创建原始图像。使用 DALL·E 3 时,图像的尺寸可以为 1024x1024、1024x1792 或 1792x1024 像素。'),
|
||||
TooltipLabel(_('Image size'), _('The image generation endpoint allows you to create raw images based on text prompts. When using the DALL·E 3, the image size can be 1024x1024, 1024x1792 or 1792x1024 pixels.')),
|
||||
required=True,
|
||||
default_value='1024x1024',
|
||||
option_list=[
|
||||
|
|
@ -26,7 +26,9 @@ class OpenAITTIModelParams(BaseForm):
|
|||
)
|
||||
|
||||
quality = forms.SingleSelect(
|
||||
TooltipLabel('图片质量', '默认情况下,图像以标准质量生成,但使用 DALL·E 3 时,您可以设置质量:“hd”以增强细节。方形、标准质量的图像生成速度最快。'),
|
||||
TooltipLabel(_('Picture quality'), _('''
|
||||
By default, images are produced in standard quality, but with DALL·E 3 you can set quality: "hd" to enhance detail. Square, standard quality images are generated fastest.
|
||||
''')),
|
||||
required=True,
|
||||
default_value='standard',
|
||||
option_list=[
|
||||
|
|
@ -38,7 +40,7 @@ class OpenAITTIModelParams(BaseForm):
|
|||
)
|
||||
|
||||
n = forms.SliderField(
|
||||
TooltipLabel('图片数量', '您可以使用 DALL·E 3 一次请求 1 个图像(通过发出并行请求来请求更多图像),或者使用带有 n 参数的 DALL·E 2 一次最多请求 10 个图像。'),
|
||||
TooltipLabel(_('Number of pictures'), _('You can use DALL·E 3 to request 1 image at a time (requesting more images by issuing parallel requests), or use DALL·E 2 with the n parameter to request up to 10 images at a time.')),
|
||||
required=True, default_value=1,
|
||||
_min=1,
|
||||
_max=10,
|
||||
|
|
@ -47,19 +49,19 @@ class OpenAITTIModelParams(BaseForm):
|
|||
|
||||
|
||||
class OpenAITextToImageModelCredential(BaseForm, BaseModelCredential):
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -70,7 +72,7 @@ class OpenAITextToImageModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class OpenAITTSModelGeneralParams(BaseForm):
|
||||
# alloy, echo, fable, onyx, nova, shimmer
|
||||
voice = forms.SingleSelect(
|
||||
TooltipLabel('Voice', '尝试不同的声音(合金、回声、寓言、缟玛瑙、新星和闪光),找到一种适合您所需的音调和听众的声音。当前的语音针对英语进行了优化。'),
|
||||
TooltipLabel('Voice', _('Try out the different sounds (Alloy, Echo, Fable, Onyx, Nova, and Sparkle) to find one that suits your desired tone and audience. The current voiceover is optimized for English.')),
|
||||
required=True, default_value='alloy',
|
||||
text_field='value',
|
||||
value_field='value',
|
||||
|
|
@ -24,19 +25,19 @@ class OpenAITTSModelGeneralParams(BaseForm):
|
|||
|
||||
|
||||
class OpenAITTSModelCredential(BaseForm, BaseModelCredential):
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -46,7 +47,7 @@ class OpenAITTSModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ from setting.models_provider.impl.openai_model_provider.model.stt import OpenAIS
|
|||
from setting.models_provider.impl.openai_model_provider.model.tti import OpenAITextToImage
|
||||
from setting.models_provider.impl.openai_model_provider.model.tts import OpenAITextToSpeech
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
openai_llm_model_credential = OpenAILLMModelCredential()
|
||||
openai_stt_model_credential = OpenAISTTModelCredential()
|
||||
|
|
@ -31,47 +32,47 @@ openai_tts_model_credential = OpenAITTSModelCredential()
|
|||
openai_image_model_credential = OpenAIImageModelCredential()
|
||||
openai_tti_model_credential = OpenAITextToImageModelCredential()
|
||||
model_info_list = [
|
||||
ModelInfo('gpt-3.5-turbo', '最新的gpt-3.5-turbo,随OpenAI调整而更新', ModelTypeConst.LLM,
|
||||
ModelInfo('gpt-3.5-turbo', _('The latest gpt-3.5-turbo, updated with OpenAI adjustments'), ModelTypeConst.LLM,
|
||||
openai_llm_model_credential, OpenAIChatModel
|
||||
),
|
||||
ModelInfo('gpt-4', '最新的gpt-4,随OpenAI调整而更新', ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
ModelInfo('gpt-4', _('Latest gpt-4, updated with OpenAI adjustments'), ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-4o', '最新的GPT-4o,比gpt-4-turbo更便宜、更快,随OpenAI调整而更新',
|
||||
ModelInfo('gpt-4o', _('The latest GPT-4o, cheaper and faster than gpt-4-turbo, updated with OpenAI adjustments'),
|
||||
ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-4o-mini', '最新的gpt-4o-mini,比gpt-4o更便宜、更快,随OpenAI调整而更新',
|
||||
ModelInfo('gpt-4o-mini', _('The latest gpt-4o-mini, cheaper and faster than gpt-4o, updated with OpenAI adjustments'),
|
||||
ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-4-turbo', '最新的gpt-4-turbo,随OpenAI调整而更新', ModelTypeConst.LLM,
|
||||
ModelInfo('gpt-4-turbo', _('The latest gpt-4-turbo, updated with OpenAI adjustments'), ModelTypeConst.LLM,
|
||||
openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-4-turbo-preview', '最新的gpt-4-turbo-preview,随OpenAI调整而更新',
|
||||
ModelInfo('gpt-4-turbo-preview', _('The latest gpt-4-turbo-preview, updated with OpenAI adjustments'),
|
||||
ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-3.5-turbo-0125',
|
||||
'2024年1月25日的gpt-3.5-turbo快照,支持上下文长度16,385 tokens', ModelTypeConst.LLM,
|
||||
_('gpt-3.5-turbo snapshot on January 25, 2024, supporting context length 16,385 tokens'), ModelTypeConst.LLM,
|
||||
openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-3.5-turbo-1106',
|
||||
'2023年11月6日的gpt-3.5-turbo快照,支持上下文长度16,385 tokens', ModelTypeConst.LLM,
|
||||
_('gpt-3.5-turbo snapshot on November 6, 2023, supporting context length 16,385 tokens'), ModelTypeConst.LLM,
|
||||
openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-3.5-turbo-0613',
|
||||
'[Legacy] 2023年6月13日的gpt-3.5-turbo快照,将于2024年6月13日弃用',
|
||||
_('[Legacy] gpt-3.5-turbo snapshot on June 13, 2023, will be deprecated on June 13, 2024'),
|
||||
ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-4o-2024-05-13',
|
||||
'2024年5月13日的gpt-4o快照,支持上下文长度128,000 tokens',
|
||||
_('gpt-4o snapshot on May 13, 2024, supporting context length 128,000 tokens'),
|
||||
ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-4-turbo-2024-04-09',
|
||||
'2024年4月9日的gpt-4-turbo快照,支持上下文长度128,000 tokens',
|
||||
_('gpt-4-turbo snapshot on April 9, 2024, supporting context length 128,000 tokens'),
|
||||
ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-4-0125-preview', '2024年1月25日的gpt-4-turbo快照,支持上下文长度128,000 tokens',
|
||||
ModelInfo('gpt-4-0125-preview', _('gpt-4-turbo snapshot on January 25, 2024, supporting context length 128,000 tokens'),
|
||||
ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('gpt-4-1106-preview', '2023年11月6日的gpt-4-turbo快照,支持上下文长度128,000 tokens',
|
||||
ModelInfo('gpt-4-1106-preview', _('gpt-4-turbo snapshot on November 6, 2023, supporting context length 128,000 tokens'),
|
||||
ModelTypeConst.LLM, openai_llm_model_credential,
|
||||
OpenAIChatModel),
|
||||
ModelInfo('whisper-1', '',
|
||||
|
|
@ -95,10 +96,10 @@ model_info_embedding_list = [
|
|||
]
|
||||
|
||||
model_info_image_list = [
|
||||
ModelInfo('gpt-4o', '最新的GPT-4o,比gpt-4-turbo更便宜、更快,随OpenAI调整而更新',
|
||||
ModelInfo('gpt-4o', _('The latest GPT-4o, cheaper and faster than gpt-4-turbo, updated with OpenAI adjustments'),
|
||||
ModelTypeConst.IMAGE, openai_image_model_credential,
|
||||
OpenAIImage),
|
||||
ModelInfo('gpt-4o-mini', '最新的gpt-4o-mini,比gpt-4o更便宜、更快,随OpenAI调整而更新',
|
||||
ModelInfo('gpt-4o-mini', _('The latest gpt-4o-mini, cheaper and faster than gpt-4o, updated with OpenAI adjustments'),
|
||||
ModelTypeConst.IMAGE, openai_image_model_credential,
|
||||
OpenAIImage),
|
||||
]
|
||||
|
|
@ -115,7 +116,7 @@ model_info_tti_list = [
|
|||
model_info_manage = (
|
||||
ModelInfoManage.builder()
|
||||
.append_model_info_list(model_info_list)
|
||||
.append_default_model_info(ModelInfo('gpt-3.5-turbo', '最新的gpt-3.5-turbo,随OpenAI调整而更新', ModelTypeConst.LLM,
|
||||
.append_default_model_info(ModelInfo('gpt-3.5-turbo', _('The latest gpt-3.5-turbo, updated with OpenAI adjustments'), ModelTypeConst.LLM,
|
||||
openai_llm_model_credential, OpenAIChatModel
|
||||
))
|
||||
.append_model_info_list(model_info_embedding_list)
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class QwenModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=1.0,
|
||||
_min=0.1,
|
||||
_max=1.9,
|
||||
|
|
@ -27,7 +27,7 @@ class QwenModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -41,23 +41,23 @@ class QwenVLModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": "你好"}])])
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": _('Hello')}])])
|
||||
for chunk in res:
|
||||
print(chunk)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class QwenModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=1.0,
|
||||
_min=0.1,
|
||||
_max=1.9,
|
||||
|
|
@ -25,7 +25,7 @@ class QwenModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -39,21 +39,21 @@ class OpenAILLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
model.invoke([HumanMessage(content='你好')])
|
||||
model.invoke([HumanMessage(content=_('Hello'))])
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -16,11 +16,10 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
class QwenModelParams(BaseForm):
|
||||
size = forms.SingleSelect(
|
||||
TooltipLabel('图片尺寸', '指定生成图片的尺寸, 如: 1024x1024'),
|
||||
TooltipLabel(_('Image size'), _('Specify the size of the generated image, such as: 1024x1024')),
|
||||
required=True,
|
||||
default_value='1024*1024',
|
||||
option_list=[
|
||||
|
|
@ -32,27 +31,27 @@ class QwenModelParams(BaseForm):
|
|||
text_field='label',
|
||||
value_field='value')
|
||||
n = forms.SliderField(
|
||||
TooltipLabel('图片数量', '指定生成图片的数量'),
|
||||
TooltipLabel(_('Number of pictures'), _('Specify the number of generated images')),
|
||||
required=True, default_value=1,
|
||||
_min=1,
|
||||
_max=4,
|
||||
_step=1,
|
||||
precision=0)
|
||||
style = forms.SingleSelect(
|
||||
TooltipLabel('风格', '指定生成图片的风格'),
|
||||
TooltipLabel(_('Style'), _('Specify the style of generated images')),
|
||||
required=True,
|
||||
default_value='<auto>',
|
||||
option_list=[
|
||||
{'value': '<auto>', 'label': '默认值,由模型随机输出图像风格'},
|
||||
{'value': '<photography>', 'label': '摄影'},
|
||||
{'value': '<portrait>', 'label': '人像写真'},
|
||||
{'value': '<3d cartoon>', 'label': '3D卡通'},
|
||||
{'value': '<anime>', 'label': '动画'},
|
||||
{'value': '<oil painting>', 'label': '油画'},
|
||||
{'value': '<watercolor>', 'label': '水彩'},
|
||||
{'value': '<sketch>', 'label': '素描'},
|
||||
{'value': '<chinese painting>', 'label': '中国画'},
|
||||
{'value': '<flat illustration>', 'label': '扁平插画'},
|
||||
{'value': '<auto>', 'label': _('Default value, the image style is randomly output by the model')},
|
||||
{'value': '<photography>', 'label': _('photography')},
|
||||
{'value': '<portrait>', 'label': _('Portraits')},
|
||||
{'value': '<3d cartoon>', 'label': _('3D cartoon')},
|
||||
{'value': '<anime>', 'label': _('animation')},
|
||||
{'value': '<oil painting>', 'label': _('painting')},
|
||||
{'value': '<watercolor>', 'label': _('watercolor')},
|
||||
{'value': '<sketch>', 'label': _('sketch')},
|
||||
{'value': '<chinese painting>', 'label': _('Chinese painting')},
|
||||
{'value': '<flat illustration>', 'label': _('flat illustration')},
|
||||
],
|
||||
text_field='label',
|
||||
value_field='value'
|
||||
|
|
@ -65,11 +64,11 @@ class QwenTextToImageModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -80,7 +79,7 @@ class QwenTextToImageModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from langchain_core.messages import HumanMessage
|
|||
|
||||
from setting.models_provider.base_model_provider import MaxKBBaseModel
|
||||
from setting.models_provider.impl.base_tti import BaseTextToImage
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class QwenTextToImageModel(MaxKBBaseModel, BaseTextToImage):
|
||||
api_key: str
|
||||
|
|
@ -39,7 +39,7 @@ class QwenTextToImageModel(MaxKBBaseModel, BaseTextToImage):
|
|||
|
||||
def check_auth(self):
|
||||
chat = ChatTongyi(api_key=self.api_key, model_name='qwen-max')
|
||||
chat.invoke([HumanMessage([{"type": "text", "text": "你好"}])])
|
||||
chat.invoke([HumanMessage([{"type": "text", "text": _('Hello')}])])
|
||||
|
||||
def generate_image(self, prompt: str, negative_prompt: str = None):
|
||||
# api_base='https://dashscope.aliyuncs.com/compatible-mode/v1',
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from setting.models_provider.impl.qwen_model_provider.model.image import QwenVLC
|
|||
from setting.models_provider.impl.qwen_model_provider.model.llm import QwenChatModel
|
||||
from setting.models_provider.impl.qwen_model_provider.model.tti import QwenTextToImageModel
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
qwen_model_credential = OpenAILLMModelCredential()
|
||||
qwenvl_model_credential = QwenVLModelCredential()
|
||||
|
|
@ -36,7 +37,7 @@ module_info_vl_list = [
|
|||
]
|
||||
module_info_tti_list = [
|
||||
ModelInfo('wanx-v1',
|
||||
'通义万相-文本生成图像大模型,支持中英文双语输入,支持输入参考图片进行参考内容或者参考风格迁移,重点风格包括但不限于水彩、油画、中国画、素描、扁平插画、二次元、3D卡通。',
|
||||
_('Tongyi Wanxiang - a large image model for text generation, supports bilingual input in Chinese and English, and supports the input of reference pictures for reference content or reference style migration. Key styles include but are not limited to watercolor, oil painting, Chinese painting, sketch, flat illustration, two-dimensional, and 3D. Cartoon.'),
|
||||
ModelTypeConst.TTI, qwentti_model_credential, QwenTextToImageModel),
|
||||
]
|
||||
|
||||
|
|
@ -59,6 +60,6 @@ class QwenModelProvider(IModelProvider):
|
|||
return model_info_manage
|
||||
|
||||
def get_model_provide_info(self):
|
||||
return ModelProvideInfo(provider='model_qwen_provider', name='通义千问', icon=get_file_content(
|
||||
return ModelProvideInfo(provider='model_qwen_provider', name=_('Tongyi Qianwen'), icon=get_file_content(
|
||||
os.path.join(PROJECT_DIR, "apps", "setting", 'models_provider', 'impl', 'qwen_model_provider', 'icon',
|
||||
'qwen_icon_svg')))
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class TencentEmbeddingCredential(BaseForm, BaseModelCredential):
|
||||
|
||||
|
|
@ -12,16 +12,16 @@ class TencentEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=True) -> bool:
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
self.valid_form(model_credential)
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential)
|
||||
model.embed_query('你好')
|
||||
model.embed_query(_('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class QwenModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=1.0,
|
||||
_min=0.1,
|
||||
_max=1.9,
|
||||
|
|
@ -27,7 +27,7 @@ class QwenModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -41,23 +41,23 @@ class TencentVisionModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
for key in ['api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": "你好"}])])
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": _('Hello')}])])
|
||||
for chunk in res:
|
||||
print(chunk)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class TencentLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.5,
|
||||
_min=0.1,
|
||||
_max=2.0,
|
||||
|
|
@ -23,7 +23,7 @@ class TencentLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
def _validate_model_type(cls, model_type, provider, raise_exception=False):
|
||||
if not any(mt['value'] == model_type for mt in provider.get_model_type_list()):
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ class TencentLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
missing_keys = [key for key in cls.REQUIRED_FIELDS if key not in model_credential]
|
||||
if missing_keys:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{", ".join(missing_keys)} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{keys} is required').format(keys=", ".join(missing_keys)))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
@ -42,10 +42,10 @@ class TencentLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
model.invoke([HumanMessage(content='你好')])
|
||||
model.invoke([HumanMessage(content=_('Hello'))])
|
||||
except Exception as e:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -5,47 +5,47 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class TencentTTIModelParams(BaseForm):
|
||||
Style = forms.SingleSelect(
|
||||
TooltipLabel('绘画风格', '不传默认使用201(日系动漫风格)'),
|
||||
TooltipLabel(_('painting style'), _('If not passed, the default value is 201 (Japanese anime style)')),
|
||||
required=True,
|
||||
default_value='201',
|
||||
option_list=[
|
||||
{'value': '000', 'label': '不限定风格'},
|
||||
{'value': '101', 'label': '水墨画'},
|
||||
{'value': '102', 'label': '概念艺术'},
|
||||
{'value': '103', 'label': '油画1'},
|
||||
{'value': '118', 'label': '油画2(梵高)'},
|
||||
{'value': '104', 'label': '水彩画'},
|
||||
{'value': '105', 'label': '像素画'},
|
||||
{'value': '106', 'label': '厚涂风格'},
|
||||
{'value': '107', 'label': '插图'},
|
||||
{'value': '108', 'label': '剪纸风格'},
|
||||
{'value': '109', 'label': '印象派1(莫奈)'},
|
||||
{'value': '119', 'label': '印象派2'},
|
||||
{'value': '000', 'label': _('Not limited to style')},
|
||||
{'value': '101', 'label': _('ink painting')},
|
||||
{'value': '102', 'label': _('concept art')},
|
||||
{'value': '103', 'label': _('Oil painting 1')},
|
||||
{'value': '118', 'label': _('Oil Painting 2 (Van Gogh)')},
|
||||
{'value': '104', 'label': _('watercolor painting')},
|
||||
{'value': '105', 'label': _('pixel art')},
|
||||
{'value': '106', 'label': _('impasto style')},
|
||||
{'value': '107', 'label': _('illustration')},
|
||||
{'value': '108', 'label': _('paper cut style')},
|
||||
{'value': '109', 'label': _('Impressionism 1 (Monet)')},
|
||||
{'value': '119', 'label': _('Impressionism 2')},
|
||||
{'value': '110', 'label': '2.5D'},
|
||||
{'value': '111', 'label': '古典肖像画'},
|
||||
{'value': '112', 'label': '黑白素描画'},
|
||||
{'value': '113', 'label': '赛博朋克'},
|
||||
{'value': '114', 'label': '科幻风格'},
|
||||
{'value': '115', 'label': '暗黑风格'},
|
||||
{'value': '111', 'label': _('classical portraiture')},
|
||||
{'value': '112', 'label': _('black and white sketch')},
|
||||
{'value': '113', 'label': _('cyberpunk')},
|
||||
{'value': '114', 'label': _('science fiction style')},
|
||||
{'value': '115', 'label': _('dark style')},
|
||||
{'value': '116', 'label': '3D'},
|
||||
{'value': '117', 'label': '蒸汽波'},
|
||||
{'value': '201', 'label': '日系动漫'},
|
||||
{'value': '202', 'label': '怪兽风格'},
|
||||
{'value': '203', 'label': '唯美古风'},
|
||||
{'value': '204', 'label': '复古动漫'},
|
||||
{'value': '301', 'label': '游戏卡通手绘'},
|
||||
{'value': '401', 'label': '通用写实风格'},
|
||||
{'value': '117', 'label': _('vaporwave')},
|
||||
{'value': '201', 'label': _('Japanese animation')},
|
||||
{'value': '202', 'label': _('monster style')},
|
||||
{'value': '203', 'label': _('Beautiful ancient style')},
|
||||
{'value': '204', 'label': _('retro anime')},
|
||||
{'value': '301', 'label': _('Game cartoon hand drawing')},
|
||||
{'value': '401', 'label': _('Universal realistic style')},
|
||||
],
|
||||
value_field='value',
|
||||
text_field='label'
|
||||
)
|
||||
|
||||
Resolution = forms.SingleSelect(
|
||||
TooltipLabel('生成图分辨率', '不传默认使用768:768。'),
|
||||
TooltipLabel(_('Generate image resolution'), _('If not transmitted, the default value is 768:768.')),
|
||||
required=True,
|
||||
default_value='768:768',
|
||||
option_list=[
|
||||
|
|
@ -72,7 +72,7 @@ class TencentTTIModelCredential(BaseForm, BaseModelCredential):
|
|||
def _validate_model_type(cls, model_type, provider, raise_exception=False):
|
||||
if not any(mt['value'] == model_type for mt in provider.get_model_type_list()):
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ class TencentTTIModelCredential(BaseForm, BaseModelCredential):
|
|||
missing_keys = [key for key in cls.REQUIRED_FIELDS if key not in model_credential]
|
||||
if missing_keys:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{", ".join(missing_keys)} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{keys} is required').format(keys=", ".join(missing_keys)))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ class TencentTTIModelCredential(BaseForm, BaseModelCredential):
|
|||
model.check_auth()
|
||||
except Exception as e:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from tencentcloud.hunyuan.v20230901 import hunyuan_client, models
|
|||
from setting.models_provider.base_model_provider import MaxKBBaseModel
|
||||
from setting.models_provider.impl.base_tti import BaseTextToImage
|
||||
from setting.models_provider.impl.tencent_model_provider.model.hunyuan import ChatHunyuan
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class TencentTextToImageModel(MaxKBBaseModel, BaseTextToImage):
|
||||
hunyuan_secret_id: str
|
||||
|
|
@ -50,7 +50,7 @@ class TencentTextToImageModel(MaxKBBaseModel, BaseTextToImage):
|
|||
hunyuan_secret_id=self.hunyuan_secret_id,
|
||||
hunyuan_secret_key=self.hunyuan_secret_key,
|
||||
model="hunyuan-standard")
|
||||
res = chat.invoke('你好')
|
||||
res = chat.invoke(_('Hello'))
|
||||
# print(res)
|
||||
|
||||
def generate_image(self, prompt: str, negative_prompt: str = None):
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from setting.models_provider.impl.tencent_model_provider.model.image import Tenc
|
|||
from setting.models_provider.impl.tencent_model_provider.model.llm import TencentModel
|
||||
from setting.models_provider.impl.tencent_model_provider.model.tti import TencentTextToImageModel
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
def _create_model_info(model_name, description, model_type, credential_class, model_class):
|
||||
return ModelInfo(
|
||||
|
|
@ -35,38 +35,44 @@ def _get_tencent_icon_path():
|
|||
def _initialize_model_info():
|
||||
model_info_list = [_create_model_info(
|
||||
'hunyuan-pro',
|
||||
'当前混元模型中效果最优版本,万亿级参数规模 MOE-32K 长文模型。在各种 benchmark 上达到绝对领先的水平,复杂指令和推理,具备复杂数学能力,支持 functioncall,在多语言翻译、金融法律医疗等领域应用重点优化',
|
||||
_('The most effective version of the current hybrid model, the trillion-level parameter scale MOE-32K long article model. Reaching the absolute leading level on various benchmarks, with complex instructions and reasoning, complex mathematical capabilities, support for function call, and application focus optimization in fields such as multi-language translation, finance, law, and medical care'),
|
||||
ModelTypeConst.LLM,
|
||||
TencentLLMModelCredential,
|
||||
TencentModel
|
||||
),
|
||||
_create_model_info(
|
||||
'hunyuan-standard',
|
||||
'采用更优的路由策略,同时缓解了负载均衡和专家趋同的问题。长文方面,大海捞针指标达到99.9%',
|
||||
_('A better routing strategy is adopted to simultaneously alleviate the problems of load balancing and expert convergence. For long articles, the needle-in-a-haystack index reaches 99.9%'),
|
||||
ModelTypeConst.LLM,
|
||||
TencentLLMModelCredential,
|
||||
TencentModel),
|
||||
_create_model_info(
|
||||
'hunyuan-lite',
|
||||
'升级为 MOE 结构,上下文窗口为 256k ,在 NLP,代码,数学,行业等多项评测集上领先众多开源模型',
|
||||
_('Upgraded to MOE structure, the context window is 256k, leading many open source models in multiple evaluation sets such as NLP, code, mathematics, industry, etc.'),
|
||||
ModelTypeConst.LLM,
|
||||
TencentLLMModelCredential,
|
||||
TencentModel),
|
||||
_create_model_info(
|
||||
'hunyuan-role',
|
||||
'混元最新版角色扮演模型,混元官方精调训练推出的角色扮演模型,基于混元模型结合角色扮演场景数据集进行增训,在角色扮演场景具有更好的基础效果',
|
||||
_('''
|
||||
Hunyuan's latest version of the role-playing model, a role-playing model launched by Hunyuan's official fine-tuning training, is based on the Hunyuan model combined with the role-playing scene data set for additional training, and has better basic effects in role-playing scenes.
|
||||
'''),
|
||||
ModelTypeConst.LLM,
|
||||
TencentLLMModelCredential,
|
||||
TencentModel),
|
||||
_create_model_info(
|
||||
'hunyuan-functioncall',
|
||||
'混元最新 MOE 架构 FunctionCall 模型,经过高质量的 FunctionCall 数据训练,上下文窗口达 32K,在多个维度的评测指标上处于领先。',
|
||||
_('''
|
||||
Hunyuan's latest MOE architecture FunctionCall model has been trained with high-quality FunctionCall data and has a context window of 32K, leading in multiple dimensions of evaluation indicators.
|
||||
'''),
|
||||
ModelTypeConst.LLM,
|
||||
TencentLLMModelCredential,
|
||||
TencentModel),
|
||||
_create_model_info(
|
||||
'hunyuan-code',
|
||||
'混元最新代码生成模型,经过 200B 高质量代码数据增训基座模型,迭代半年高质量 SFT 数据训练,上下文长窗口长度增大到 8K,五大语言代码生成自动评测指标上位居前列;五大语言10项考量各方面综合代码任务人工高质量评测上,性能处于第一梯队',
|
||||
_('''
|
||||
Hunyuan's latest code generation model, after training the base model with 200B high-quality code data, and iterating on high-quality SFT data for half a year, the context long window length has been increased to 8K, and it ranks among the top in the automatic evaluation indicators of code generation in the five major languages; the five major languages In the manual high-quality evaluation of 10 comprehensive code tasks that consider all aspects, the performance is in the first echelon.
|
||||
'''),
|
||||
ModelTypeConst.LLM,
|
||||
TencentLLMModelCredential,
|
||||
TencentModel),
|
||||
|
|
@ -74,7 +80,9 @@ def _initialize_model_info():
|
|||
|
||||
tencent_embedding_model_info = _create_model_info(
|
||||
'hunyuan-embedding',
|
||||
'腾讯混元 Embedding 接口,可以将文本转化为高质量的向量数据。向量维度为1024维。',
|
||||
_('''
|
||||
Tencent's Hunyuan Embedding interface can convert text into high-quality vector data. The vector dimension is 1024 dimensions.
|
||||
'''),
|
||||
ModelTypeConst.EMBEDDING,
|
||||
TencentEmbeddingCredential,
|
||||
TencentEmbeddingModel
|
||||
|
|
@ -84,14 +92,14 @@ def _initialize_model_info():
|
|||
|
||||
model_info_vision_list = [_create_model_info(
|
||||
'hunyuan-vision',
|
||||
'混元视觉模型',
|
||||
_('Mixed element visual model'),
|
||||
ModelTypeConst.IMAGE,
|
||||
TencentVisionModelCredential,
|
||||
TencentVision)]
|
||||
|
||||
model_info_tti_list = [_create_model_info(
|
||||
'hunyuan-dit',
|
||||
'混元生图模型',
|
||||
_('Hunyuan graph model'),
|
||||
ModelTypeConst.TTI,
|
||||
TencentTTIModelCredential,
|
||||
TencentTextToImageModel)]
|
||||
|
|
@ -122,6 +130,6 @@ class TencentModelProvider(IModelProvider):
|
|||
icon_data = get_file_content(icon_path)
|
||||
return ModelProvideInfo(
|
||||
provider='model_tencent_provider',
|
||||
name='腾讯混元',
|
||||
name=_('Tencent Hunyuan'),
|
||||
icon=icon_data
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class VLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.7,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -19,7 +20,7 @@ class VLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=800,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -32,17 +33,17 @@ class VLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
try:
|
||||
model_list = provider.get_base_model_list(model_credential.get('api_base'), model_credential.get('api_key'))
|
||||
except Exception as e:
|
||||
raise AppApiException(ValidCode.valid_error.value, "API 域名无效")
|
||||
raise AppApiException(ValidCode.valid_error.value, _('API domain name is invalid'))
|
||||
exist = provider.get_model_info_by_name(model_list, model_name)
|
||||
if len(exist) == 0:
|
||||
raise AppApiException(ValidCode.valid_error.value, "模型不存在,请先下载模型")
|
||||
raise AppApiException(ValidCode.valid_error.value, _('The model does not exist, please download the model first'))
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
try:
|
||||
res = model.invoke([HumanMessage(content='你好')])
|
||||
res = model.invoke([HumanMessage(content=_('Hello'))])
|
||||
print(res)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
|
@ -54,11 +55,11 @@ class VLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
def build_model(self, model_info: Dict[str, object]):
|
||||
for key in ['api_key', 'model']:
|
||||
if key not in model_info:
|
||||
raise AppApiException(500, f'{key} 字段为必填字段')
|
||||
raise AppApiException(500, _('{key} is required').format(key=key))
|
||||
self.api_key = model_info.get('api_key')
|
||||
return self
|
||||
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
||||
def get_model_params_setting_form(self, model_name):
|
||||
|
|
|
|||
|
|
@ -10,19 +10,20 @@ from setting.models_provider.base_model_provider import IModelProvider, ModelPro
|
|||
from setting.models_provider.impl.vllm_model_provider.credential.llm import VLLMModelCredential
|
||||
from setting.models_provider.impl.vllm_model_provider.model.llm import VllmChatModel
|
||||
from smartdoc.conf import PROJECT_DIR
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
v_llm_model_credential = VLLMModelCredential()
|
||||
model_info_list = [
|
||||
ModelInfo('facebook/opt-125m', 'Facebook的125M参数模型', ModelTypeConst.LLM, v_llm_model_credential, VllmChatModel),
|
||||
ModelInfo('BAAI/Aquila-7B', 'BAAI的7B参数模型', ModelTypeConst.LLM, v_llm_model_credential, VllmChatModel),
|
||||
ModelInfo('BAAI/AquilaChat-7B', 'BAAI的13B参数模型', ModelTypeConst.LLM, v_llm_model_credential, VllmChatModel),
|
||||
ModelInfo('facebook/opt-125m', _('Facebook’s 125M parameter model'), ModelTypeConst.LLM, v_llm_model_credential, VllmChatModel),
|
||||
ModelInfo('BAAI/Aquila-7B', _('BAAI’s 7B parameter model'), ModelTypeConst.LLM, v_llm_model_credential, VllmChatModel),
|
||||
ModelInfo('BAAI/AquilaChat-7B', _('BAAI’s 13B parameter mode'), ModelTypeConst.LLM, v_llm_model_credential, VllmChatModel),
|
||||
|
||||
]
|
||||
|
||||
model_info_manage = (ModelInfoManage.builder().append_model_info_list(model_info_list).append_default_model_info(
|
||||
ModelInfo(
|
||||
'facebook/opt-125m',
|
||||
'Facebook的125M参数模型',
|
||||
_('Facebook’s 125M parameter model'),
|
||||
ModelTypeConst.LLM, v_llm_model_credential, VllmChatModel))
|
||||
.build())
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class VolcanicEmbeddingCredential(BaseForm, BaseModelCredential):
|
||||
|
|
@ -19,22 +20,22 @@ class VolcanicEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=True):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_base', 'api_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential)
|
||||
model.embed_query('你好')
|
||||
model.embed_query(_('Hello'))
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
@ -42,5 +43,5 @@ class VolcanicEmbeddingCredential(BaseForm, BaseModelCredential):
|
|||
def encryption_dict(self, model: Dict[str, object]):
|
||||
return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
|
||||
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class VolcanicEngineImageModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.95,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -19,7 +20,7 @@ class VolcanicEngineImageModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=1024,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -28,30 +29,30 @@ class VolcanicEngineImageModelParams(BaseForm):
|
|||
|
||||
class VolcanicEngineImageModelCredential(BaseForm, BaseModelCredential):
|
||||
api_key = forms.PasswordInputField('API Key', required=True)
|
||||
api_base = forms.TextInputField('API 域名', required=True)
|
||||
api_base = forms.TextInputField('API Url', required=True)
|
||||
|
||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['api_key', 'api_base']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": "你好"}])])
|
||||
res = model.stream([HumanMessage(content=[{"type": "text", "text": _('Hello')}])])
|
||||
for chunk in res:
|
||||
print(chunk)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class VolcanicEngineLLMModelParams(BaseForm):
|
||||
temperature = forms.SliderField(TooltipLabel('温度', '较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定'),
|
||||
temperature = forms.SliderField(TooltipLabel(_('Temperature'), _('Higher values make the output more random, while lower values make it more focused and deterministic')),
|
||||
required=True, default_value=0.3,
|
||||
_min=0.1,
|
||||
_max=1.0,
|
||||
|
|
@ -25,7 +26,7 @@ class VolcanicEngineLLMModelParams(BaseForm):
|
|||
precision=2)
|
||||
|
||||
max_tokens = forms.SliderField(
|
||||
TooltipLabel('输出最大Tokens', '指定模型可生成的最大token个数'),
|
||||
TooltipLabel(_('Output the maximum Tokens'), _('Specify the maximum number of tokens that the model can generate')),
|
||||
required=True, default_value=1024,
|
||||
_min=1,
|
||||
_max=100000,
|
||||
|
|
@ -39,23 +40,23 @@ class VolcanicEngineLLMModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['access_key_id', 'secret_access_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||
res = model.invoke([HumanMessage(content='你好')])
|
||||
res = model.invoke([HumanMessage(content=_('Hello'))])
|
||||
print(res)
|
||||
except Exception as e:
|
||||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class VolcanicEngineSTTModelCredential(BaseForm, BaseModelCredential):
|
||||
volcanic_api_url = forms.TextInputField('API 域名', required=True, default_value='wss://openspeech.bytedance.com/api/v2/asr')
|
||||
volcanic_api_url = forms.TextInputField('API Url', required=True, default_value='wss://openspeech.bytedance.com/api/v2/asr')
|
||||
volcanic_app_id = forms.TextInputField('App ID', required=True)
|
||||
volcanic_token = forms.PasswordInputField('Access Token', required=True)
|
||||
volcanic_cluster = forms.TextInputField('Cluster ID', required=True)
|
||||
|
|
@ -18,12 +19,12 @@ class VolcanicEngineSTTModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['volcanic_api_url', 'volcanic_app_id', 'volcanic_token', 'volcanic_cluster']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -33,7 +34,7 @@ class VolcanicEngineSTTModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class VolcanicEngineTTIModelGeneralParams(BaseForm):
|
||||
size = forms.SingleSelect(
|
||||
TooltipLabel('图片尺寸',
|
||||
'宽、高与512差距过大,则出图效果不佳、延迟过长概率显著增加。超分前建议比例及对应宽高:width*height'),
|
||||
TooltipLabel(_('Image size'),
|
||||
_('If the gap between width, height and 512 is too large, the picture rendering effect will be poor and the probability of excessive delay will increase significantly. Recommended ratio and corresponding width and height before super score: width*height')),
|
||||
required=True,
|
||||
default_value='512*512',
|
||||
option_list=[
|
||||
|
|
@ -35,12 +36,12 @@ class VolcanicEngineTTIModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['access_key', 'secret_key']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -50,7 +51,7 @@ class VolcanicEngineTTIModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -6,29 +6,30 @@ from common import forms
|
|||
from common.exception.app_exception import AppApiException
|
||||
from common.forms import BaseForm, TooltipLabel
|
||||
from setting.models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class VolcanicEngineTTSModelGeneralParams(BaseForm):
|
||||
voice_type = forms.SingleSelect(
|
||||
TooltipLabel('音色', '中文音色可支持中英文混合场景'),
|
||||
TooltipLabel(_('timbre'), _('Chinese sounds can support mixed scenes of Chinese and English')),
|
||||
required=True, default_value='BV002_streaming',
|
||||
text_field='value',
|
||||
value_field='value',
|
||||
option_list=[
|
||||
{'text': '灿灿 2.0', 'value': 'BV700_V2_streaming'},
|
||||
{'text': '炀炀', 'value': 'BV705_streaming'},
|
||||
{'text': '擎苍 2.0', 'value': 'BV701_V2_streaming'},
|
||||
{'text': '通用女声 2.0', 'value': 'BV001_V2_streaming'},
|
||||
{'text': '灿灿', 'value': 'BV700_streaming'},
|
||||
{'text': '超自然音色-梓梓2.0', 'value': 'BV406_V2_streaming'},
|
||||
{'text': '超自然音色-梓梓', 'value': 'BV406_streaming'},
|
||||
{'text': '超自然音色-燃燃2.0', 'value': 'BV407_V2_streaming'},
|
||||
{'text': '超自然音色-燃燃', 'value': 'BV407_streaming'},
|
||||
{'text': '通用女声', 'value': 'BV001_streaming'},
|
||||
{'text': '通用男声', 'value': 'BV002_streaming'},
|
||||
{'text': 'CanCan 2.0', 'value': 'BV700_V2_streaming'},
|
||||
{'text': 'Yangyang', 'value': 'BV705_streaming'},
|
||||
{'text': 'Qingcang 2.0', 'value': 'BV701_V2_streaming'},
|
||||
{'text': _('Universal female voice'), 'value': 'BV001_V2_streaming'},
|
||||
{'text': 'CanCan', 'value': 'BV700_streaming'},
|
||||
{'text': _('Supernatural timbre-ZiZi 2.0'), 'value': 'BV406_V2_streaming'},
|
||||
{'text': _('Supernatural timbre-ZiZi'), 'value': 'BV406_streaming'},
|
||||
{'text': _('Supernatural sound-Ranran 2.0'), 'value': 'BV407_V2_streaming'},
|
||||
{'text': _('Supernatural sound-Ranran'), 'value': 'BV407_streaming'},
|
||||
{'text': _('Universal female voice'), 'value': 'BV001_streaming'},
|
||||
{'text': _('Universal male voice'), 'value': 'BV002_streaming'},
|
||||
])
|
||||
speed_ratio = forms.SliderField(
|
||||
TooltipLabel('语速', '[0.2,3],默认为1,通常保留一位小数即可'),
|
||||
TooltipLabel(_('speaking speed'), _('[0.2,3], the default is 1, usually one decimal place is enough')),
|
||||
required=True, default_value=1,
|
||||
_min=0.2,
|
||||
_max=3,
|
||||
|
|
@ -37,7 +38,7 @@ class VolcanicEngineTTSModelGeneralParams(BaseForm):
|
|||
|
||||
|
||||
class VolcanicEngineTTSModelCredential(BaseForm, BaseModelCredential):
|
||||
volcanic_api_url = forms.TextInputField('API 域名', required=True, default_value='wss://openspeech.bytedance.com/api/v1/tts/ws_binary')
|
||||
volcanic_api_url = forms.TextInputField('API Url', required=True, default_value='wss://openspeech.bytedance.com/api/v1/tts/ws_binary')
|
||||
volcanic_app_id = forms.TextInputField('App ID', required=True)
|
||||
volcanic_token = forms.PasswordInputField('Access Token', required=True)
|
||||
volcanic_cluster = forms.TextInputField('Cluster ID', required=True)
|
||||
|
|
@ -46,12 +47,12 @@ class VolcanicEngineTTSModelCredential(BaseForm, BaseModelCredential):
|
|||
raise_exception=False):
|
||||
model_type_list = provider.get_model_type_list()
|
||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{model_type} 模型类型不支持')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{model_type} Model type is not supported').format(model_type=model_type))
|
||||
|
||||
for key in ['volcanic_api_url', 'volcanic_app_id', 'volcanic_token', 'volcanic_cluster']:
|
||||
if key not in model_credential:
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'{key} 字段为必填字段')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('{key} is required').format(key=key))
|
||||
else:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -61,7 +62,7 @@ class VolcanicEngineTTSModelCredential(BaseForm, BaseModelCredential):
|
|||
if isinstance(e, AppApiException):
|
||||
raise e
|
||||
if raise_exception:
|
||||
raise AppApiException(ValidCode.valid_error.value, f'校验失败,请检查参数是否正确: {str(e)}')
|
||||
raise AppApiException(ValidCode.valid_error.value, _('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e)))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import websockets
|
|||
from common.util.common import _remove_empty_lines
|
||||
from setting.models_provider.base_model_provider import MaxKBBaseModel
|
||||
from setting.models_provider.impl.base_tts import BaseTextToSpeech
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
MESSAGE_TYPES = {11: "audio-only server response", 12: "frontend server response", 15: "error message from server"}
|
||||
MESSAGE_TYPE_SPECIFIC_FLAGS = {0: "no sequence number", 1: "sequence number > 0",
|
||||
|
|
@ -72,7 +73,7 @@ class VolcanicEngineTextToSpeech(MaxKBBaseModel, BaseTextToSpeech):
|
|||
)
|
||||
|
||||
def check_auth(self):
|
||||
self.text_to_speech('你好')
|
||||
self.text_to_speech(_('Hello'))
|
||||
|
||||
def text_to_speech(self, text):
|
||||
request_json = {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue