feat: Simple application version (#3479)
This commit is contained in:
parent
77d90e5b46
commit
e21d53b746
@ -55,7 +55,7 @@ class ApplicationVersionOperateAPI(APIMixin):
|
||||
def get_parameters():
|
||||
return [
|
||||
OpenApiParameter(
|
||||
name="work_flow_version_id",
|
||||
name="application_version_id",
|
||||
description="工作流版本id",
|
||||
type=OpenApiTypes.STR,
|
||||
location='path',
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
# Generated by Django 5.2.3 on 2025-07-04 03:18
|
||||
|
||||
import application.models.application
|
||||
import django.db.models.deletion
|
||||
import uuid_utils.compat
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('application', '0003_chat_asker_chat_meta_and_more'),
|
||||
('users', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='application',
|
||||
name='publish_time',
|
||||
field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='发布时间'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ApplicationVersion',
|
||||
fields=[
|
||||
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('update_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')),
|
||||
('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')),
|
||||
('name', models.CharField(default='', max_length=128, verbose_name='版本名称')),
|
||||
('publish_user_id', models.UUIDField(default=None, null=True, verbose_name='发布者id')),
|
||||
('publish_user_name', models.CharField(default='', max_length=128, verbose_name='发布者名称')),
|
||||
('workspace_id', models.CharField(db_index=True, default='default', max_length=64, verbose_name='工作空间id')),
|
||||
('application_name', models.CharField(max_length=128, verbose_name='应用名称')),
|
||||
('desc', models.CharField(default='', max_length=512, verbose_name='引用描述')),
|
||||
('prologue', models.CharField(default='', max_length=40960, verbose_name='开场白')),
|
||||
('dialogue_number', models.IntegerField(default=0, verbose_name='会话数量')),
|
||||
('model_id', models.UUIDField(blank=True, null=True, verbose_name='大语言模型')),
|
||||
('knowledge_setting', models.JSONField(default=application.models.application.get_dataset_setting_dict, verbose_name='数据集参数设置')),
|
||||
('model_setting', models.JSONField(default=application.models.application.get_model_setting_dict, verbose_name='模型参数相关设置')),
|
||||
('model_params_setting', models.JSONField(default=dict, verbose_name='模型参数相关设置')),
|
||||
('tts_model_params_setting', models.JSONField(default=dict, verbose_name='模型参数相关设置')),
|
||||
('problem_optimization', models.BooleanField(default=False, verbose_name='问题优化')),
|
||||
('icon', models.CharField(default='./favicon.ico', max_length=256, verbose_name='应用icon')),
|
||||
('work_flow', models.JSONField(default=dict, verbose_name='工作流数据')),
|
||||
('type', models.CharField(choices=[('SIMPLE', '简易'), ('WORK_FLOW', '工作流')], default='SIMPLE', max_length=256, verbose_name='应用类型')),
|
||||
('problem_optimization_prompt', models.CharField(blank=True, default='()里面是用户问题,根据上下文回答揣测用户问题({question}) 要求: 输出一个补全问题,并且放在<data></data>标签中', max_length=102400, null=True, verbose_name='问题优化提示词')),
|
||||
('tts_model_id', models.UUIDField(blank=True, null=True, verbose_name='文本转语音模型id')),
|
||||
('stt_model_id', models.UUIDField(blank=True, null=True, verbose_name='语音转文本模型id')),
|
||||
('tts_model_enable', models.BooleanField(default=False, verbose_name='语音合成模型是否启用')),
|
||||
('stt_model_enable', models.BooleanField(default=False, verbose_name='语音识别模型是否启用')),
|
||||
('tts_type', models.CharField(default='BROWSER', max_length=20, verbose_name='语音播放类型')),
|
||||
('tts_autoplay', models.BooleanField(default=False, verbose_name='自动播放')),
|
||||
('stt_autosend', models.BooleanField(default=False, verbose_name='自动发送')),
|
||||
('clean_time', models.IntegerField(default=180, verbose_name='清理时间')),
|
||||
('file_upload_enable', models.BooleanField(default=False, verbose_name='文件上传是否启用')),
|
||||
('file_upload_setting', models.JSONField(default=dict, verbose_name='文件上传相关设置')),
|
||||
('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='application.application')),
|
||||
('user', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.user')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'application_version',
|
||||
},
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='WorkFlowVersion',
|
||||
),
|
||||
]
|
||||
@ -90,6 +90,7 @@ class Application(AppModelMixin):
|
||||
tts_autoplay = models.BooleanField(verbose_name="自动播放", default=False)
|
||||
stt_autosend = models.BooleanField(verbose_name="自动发送", default=False)
|
||||
clean_time = models.IntegerField(verbose_name="清理时间", default=180)
|
||||
publish_time = models.DateTimeField(verbose_name="发布时间", default=None, null=True, blank=True)
|
||||
file_upload_enable = models.BooleanField(verbose_name="文件上传是否启用", default=False)
|
||||
file_upload_setting = models.JSONField(verbose_name="文件上传相关设置", default=dict)
|
||||
|
||||
@ -120,14 +121,43 @@ class ApplicationKnowledgeMapping(AppModelMixin):
|
||||
db_table = "application_knowledge_mapping"
|
||||
|
||||
|
||||
class WorkFlowVersion(AppModelMixin):
|
||||
class ApplicationVersion(AppModelMixin):
|
||||
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id")
|
||||
application = models.ForeignKey(Application, on_delete=models.CASCADE)
|
||||
workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True)
|
||||
name = models.CharField(verbose_name="版本名称", max_length=128, default="")
|
||||
publish_user_id = models.UUIDField(verbose_name="发布者id", max_length=128, default=None, null=True)
|
||||
publish_user_name = models.CharField(verbose_name="发布者名称", max_length=128, default="")
|
||||
workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True)
|
||||
application_name = models.CharField(max_length=128, verbose_name="应用名称")
|
||||
desc = models.CharField(max_length=512, verbose_name="引用描述", default="")
|
||||
prologue = models.CharField(max_length=40960, verbose_name="开场白", default="")
|
||||
dialogue_number = models.IntegerField(default=0, verbose_name="会话数量")
|
||||
user = models.ForeignKey(User, on_delete=models.SET_NULL, db_constraint=False, blank=True, null=True)
|
||||
model_id = models.UUIDField(verbose_name="大语言模型", blank=True, null=True)
|
||||
knowledge_setting = models.JSONField(verbose_name="数据集参数设置", default=get_dataset_setting_dict)
|
||||
model_setting = models.JSONField(verbose_name="模型参数相关设置", default=get_model_setting_dict)
|
||||
model_params_setting = models.JSONField(verbose_name="模型参数相关设置", default=dict)
|
||||
tts_model_params_setting = models.JSONField(verbose_name="模型参数相关设置", default=dict)
|
||||
problem_optimization = models.BooleanField(verbose_name="问题优化", default=False)
|
||||
icon = models.CharField(max_length=256, verbose_name="应用icon", default="./favicon.ico")
|
||||
work_flow = models.JSONField(verbose_name="工作流数据", default=dict)
|
||||
type = models.CharField(verbose_name="应用类型", choices=ApplicationTypeChoices.choices,
|
||||
default=ApplicationTypeChoices.SIMPLE, max_length=256)
|
||||
problem_optimization_prompt = models.CharField(verbose_name="问题优化提示词", max_length=102400, blank=True,
|
||||
null=True,
|
||||
default="()里面是用户问题,根据上下文回答揣测用户问题({question}) 要求: 输出一个补全问题,并且放在<data></data>标签中")
|
||||
tts_model_id = models.UUIDField(verbose_name="文本转语音模型id",
|
||||
blank=True, null=True)
|
||||
stt_model_id = models.UUIDField(verbose_name="语音转文本模型id",
|
||||
blank=True, null=True)
|
||||
tts_model_enable = models.BooleanField(verbose_name="语音合成模型是否启用", default=False)
|
||||
stt_model_enable = models.BooleanField(verbose_name="语音识别模型是否启用", default=False)
|
||||
tts_type = models.CharField(verbose_name="语音播放类型", max_length=20, default="BROWSER")
|
||||
tts_autoplay = models.BooleanField(verbose_name="自动播放", default=False)
|
||||
stt_autosend = models.BooleanField(verbose_name="自动发送", default=False)
|
||||
clean_time = models.IntegerField(verbose_name="清理时间", default=180)
|
||||
file_upload_enable = models.BooleanField(verbose_name="文件上传是否启用", default=False)
|
||||
file_upload_setting = models.JSONField(verbose_name="文件上传相关设置", default=dict)
|
||||
|
||||
class Meta:
|
||||
db_table = "application_work_flow_version"
|
||||
db_table = "application_version"
|
||||
|
||||
@ -27,7 +27,7 @@ from rest_framework.utils.formatting import lazy_format
|
||||
|
||||
from application.flow.common import Workflow
|
||||
from application.models.application import Application, ApplicationTypeChoices, ApplicationKnowledgeMapping, \
|
||||
ApplicationFolder, WorkFlowVersion
|
||||
ApplicationFolder, ApplicationVersion
|
||||
from application.models.application_access_token import ApplicationAccessToken
|
||||
from common import result
|
||||
from common.database_model_manage.database_model_manage import DatabaseModelManage
|
||||
@ -614,6 +614,8 @@ class ApplicationOperateSerializer(serializers.Serializer):
|
||||
def delete(self, with_valid=True):
|
||||
if with_valid:
|
||||
self.is_valid()
|
||||
QuerySet(ApplicationVersion).filter(application_id=self.data.get('application_id')).delete()
|
||||
QuerySet(ApplicationKnowledgeMapping).filter(application_id=self.data.get('application_id')).delete()
|
||||
QuerySet(Application).filter(id=self.data.get('application_id')).delete()
|
||||
return True
|
||||
|
||||
@ -644,6 +646,27 @@ class ApplicationOperateSerializer(serializers.Serializer):
|
||||
except Exception as e:
|
||||
return result.error(str(e), response_status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
@staticmethod
|
||||
def reset_application_version(application_version, application):
|
||||
update_field_dict = {
|
||||
'application_name': 'name', 'desc': 'desc', 'prologue': 'prologue', 'dialogue_number': 'dialogue_number',
|
||||
'user_id': 'user_id', 'model_id': 'model_id', 'knowledge_setting': 'knowledge_setting',
|
||||
'model_setting': 'model_setting', 'model_params_setting': 'model_params_setting',
|
||||
'tts_model_params_setting': 'tts_model_params_setting',
|
||||
'problem_optimization': 'problem_optimization', 'icon': 'icon', 'work_flow': 'work_flow',
|
||||
'problem_optimization_prompt': 'problem_optimization_prompt', 'tts_model_id': 'tts_model_id',
|
||||
'stt_model_id': 'stt_model_id', 'tts_model_enable': 'tts_model_enable',
|
||||
'stt_model_enable': 'stt_model_enable', 'tts_type': 'tts_type',
|
||||
'tts_autoplay': 'tts_autoplay', 'stt_autosend': 'stt_autosend', 'file_upload_enable': 'file_upload_enable',
|
||||
'file_upload_setting': 'file_upload_setting',
|
||||
'type': 'type'
|
||||
}
|
||||
|
||||
for (version_field, app_field) in update_field_dict.items():
|
||||
_v = getattr(application, app_field)
|
||||
if _v:
|
||||
setattr(application_version, version_field, _v)
|
||||
|
||||
@transaction.atomic
|
||||
def publish(self, instance, with_valid=True):
|
||||
if with_valid:
|
||||
@ -653,25 +676,28 @@ class ApplicationOperateSerializer(serializers.Serializer):
|
||||
user = QuerySet(User).filter(id=user_id).first()
|
||||
application = QuerySet(Application).filter(id=self.data.get("application_id"),
|
||||
workspace_id=workspace_id).first()
|
||||
work_flow = instance.get('work_flow')
|
||||
if work_flow is None:
|
||||
raise AppApiException(500, _("work_flow is a required field"))
|
||||
Workflow.new_instance(work_flow).is_valid()
|
||||
base_node = get_base_node_work_flow(work_flow)
|
||||
if base_node is not None:
|
||||
node_data = base_node.get('properties').get('node_data')
|
||||
if node_data is not None:
|
||||
application.name = node_data.get('name')
|
||||
application.desc = node_data.get('desc')
|
||||
application.prologue = node_data.get('prologue')
|
||||
application.work_flow = work_flow
|
||||
if application.type == ApplicationTypeChoices.WORK_FLOW:
|
||||
work_flow = application.work_flow
|
||||
if work_flow is None:
|
||||
raise AppApiException(500, _("work_flow is a required field"))
|
||||
Workflow.new_instance(work_flow).is_valid()
|
||||
base_node = get_base_node_work_flow(work_flow)
|
||||
if base_node is not None:
|
||||
node_data = base_node.get('properties').get('node_data')
|
||||
if node_data is not None:
|
||||
application.name = node_data.get('name')
|
||||
application.desc = node_data.get('desc')
|
||||
application.prologue = node_data.get('prologue')
|
||||
application.work_flow = work_flow
|
||||
application.publish_time = datetime.datetime.now()
|
||||
application.is_publish = True
|
||||
application.save()
|
||||
work_flow_version = WorkFlowVersion(work_flow=work_flow, application=application,
|
||||
name=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
publish_user_id=user_id,
|
||||
publish_user_name=user.username,
|
||||
workspace_id=workspace_id)
|
||||
work_flow_version = ApplicationVersion(work_flow=application.work_flow, application=application,
|
||||
name=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
publish_user_id=user_id,
|
||||
publish_user_name=user.username,
|
||||
workspace_id=workspace_id)
|
||||
self.reset_application_version(work_flow_version, application)
|
||||
work_flow_version.save()
|
||||
return self.one(with_valid=False)
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ from django.db.models import QuerySet
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.models import WorkFlowVersion, Application
|
||||
from application.models import Application, ApplicationVersion
|
||||
from common.db.search import page_search
|
||||
from common.exception.app_exception import AppApiException
|
||||
|
||||
@ -25,7 +25,7 @@ class ApplicationVersionQuerySerializer(serializers.Serializer):
|
||||
|
||||
class ApplicationVersionModelSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = WorkFlowVersion
|
||||
model = ApplicationVersion
|
||||
fields = ['id', 'name', 'workspace_id', 'application_id', 'work_flow', 'publish_user_id', 'publish_user_name',
|
||||
'create_time',
|
||||
'update_time']
|
||||
@ -43,11 +43,11 @@ class ApplicationVersionSerializer(serializers.Serializer):
|
||||
workspace_id = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_("Workspace ID"))
|
||||
|
||||
def get_query_set(self, query):
|
||||
query_set = QuerySet(WorkFlowVersion).filter(application_id=query.get('application_id'))
|
||||
query_set = QuerySet(ApplicationVersion).filter(application_id=query.get('application_id'))
|
||||
if 'name' in query and query.get('name') is not None:
|
||||
query_set = query_set.filter(name__contains=query.get('name'))
|
||||
if 'workspace_id' in self.data and self.data.get('workspace_id') is not None:
|
||||
query_set = query_set.filter(workspace_id=self.data.get('workspace_id').get('name'))
|
||||
query_set = query_set.filter(workspace_id=self.data.get('workspace_id'))
|
||||
return query_set.order_by("-create_time")
|
||||
|
||||
def list(self, query, with_valid=True):
|
||||
@ -67,8 +67,8 @@ class ApplicationVersionSerializer(serializers.Serializer):
|
||||
class Operate(serializers.Serializer):
|
||||
workspace_id = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_("Workspace ID"))
|
||||
application_id = serializers.UUIDField(required=True, label=_("Application ID"))
|
||||
work_flow_version_id = serializers.UUIDField(required=True,
|
||||
label=_("Workflow version id"))
|
||||
application_version_id = serializers.UUIDField(required=True,
|
||||
label=_("Application version ID"))
|
||||
|
||||
def is_valid(self, *, raise_exception=False):
|
||||
super().is_valid(raise_exception=True)
|
||||
@ -82,10 +82,11 @@ class ApplicationVersionSerializer(serializers.Serializer):
|
||||
def one(self, with_valid=True):
|
||||
if with_valid:
|
||||
self.is_valid(raise_exception=True)
|
||||
work_flow_version = QuerySet(WorkFlowVersion).filter(application_id=self.data.get('application_id'),
|
||||
id=self.data.get('work_flow_version_id')).first()
|
||||
if work_flow_version is not None:
|
||||
return ApplicationVersionModelSerializer(work_flow_version).data
|
||||
application_version = QuerySet(ApplicationVersion).filter(application_id=self.data.get('application_id'),
|
||||
id=self.data.get(
|
||||
'application_version_id')).first()
|
||||
if application_version is not None:
|
||||
return ApplicationVersionModelSerializer(application_version).data
|
||||
else:
|
||||
raise AppApiException(500, _('Workflow version does not exist'))
|
||||
|
||||
@ -93,13 +94,14 @@ class ApplicationVersionSerializer(serializers.Serializer):
|
||||
if with_valid:
|
||||
self.is_valid(raise_exception=True)
|
||||
ApplicationVersionEditSerializer(data=instance).is_valid(raise_exception=True)
|
||||
work_flow_version = QuerySet(WorkFlowVersion).filter(application_id=self.data.get('application_id'),
|
||||
id=self.data.get('work_flow_version_id')).first()
|
||||
if work_flow_version is not None:
|
||||
application_version = QuerySet(ApplicationVersion).filter(application_id=self.data.get('application_id'),
|
||||
id=self.data.get(
|
||||
'application_version_id')).first()
|
||||
if application_version is not None:
|
||||
name = instance.get('name', None)
|
||||
if name is not None and len(name) > 0:
|
||||
work_flow_version.name = name
|
||||
work_flow_version.save()
|
||||
return ApplicationVersionModelSerializer(work_flow_version).data
|
||||
application_version.name = name
|
||||
application_version.save()
|
||||
return ApplicationVersionModelSerializer(application_version).data
|
||||
else:
|
||||
raise AppApiException(500, _('Workflow version does not exist'))
|
||||
|
||||
@ -14,8 +14,9 @@ from django.db.models import QuerySet
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from application.chat_pipeline.step.chat_step.i_chat_step import PostResponseHandler
|
||||
from application.models import Application, WorkFlowVersion, ChatRecord, Chat
|
||||
from application.models import Application, ChatRecord, Chat, ApplicationVersion
|
||||
from common.constants.cache_version import Cache_Version
|
||||
from common.exception.app_exception import ChatException
|
||||
from models_provider.models import Model
|
||||
from models_provider.tools import get_model_credential
|
||||
|
||||
@ -28,8 +29,6 @@ class ChatInfo:
|
||||
knowledge_id_list: List[str],
|
||||
exclude_document_id_list: list[str],
|
||||
application_id: str,
|
||||
application: Application,
|
||||
work_flow_version: WorkFlowVersion = None,
|
||||
debug=False):
|
||||
"""
|
||||
:param chat_id: 对话id
|
||||
@ -38,18 +37,16 @@ class ChatInfo:
|
||||
:param knowledge_id_list: 知识库列表
|
||||
:param exclude_document_id_list: 排除的文档
|
||||
:param application_id 应用id
|
||||
:param application: 应用信息
|
||||
:param debug 是否是调试
|
||||
"""
|
||||
self.chat_id = chat_id
|
||||
self.chat_user_id = chat_user_id
|
||||
self.chat_user_type = chat_user_type
|
||||
self.application = application
|
||||
self.knowledge_id_list = knowledge_id_list
|
||||
self.exclude_document_id_list = exclude_document_id_list
|
||||
self.application_id = application_id
|
||||
self.chat_record_list: List[ChatRecord] = []
|
||||
self.work_flow_version = work_flow_version
|
||||
self.application = None
|
||||
self.debug = debug
|
||||
|
||||
@staticmethod
|
||||
@ -63,10 +60,24 @@ class ChatInfo:
|
||||
no_references_setting['value'] = no_references_prompt if len(no_references_prompt) > 0 else "{question}"
|
||||
return no_references_setting
|
||||
|
||||
def get_application(self):
|
||||
if self.debug:
|
||||
application = QuerySet(Application).filter(id=self.application_id).first()
|
||||
if not application:
|
||||
raise ChatException(500, _('The application does not exist'))
|
||||
else:
|
||||
application = QuerySet(ApplicationVersion).filter(application_id=self.application_id).order_by(
|
||||
'-create_time')[0:1].first()
|
||||
if not application:
|
||||
raise ChatException(500, _("The application has not been published. Please use it after publishing."))
|
||||
self.application = application
|
||||
return application
|
||||
|
||||
def to_base_pipeline_manage_params(self):
|
||||
self.get_application()
|
||||
knowledge_setting = self.application.knowledge_setting
|
||||
model_setting = self.application.model_setting
|
||||
model_id = self.application.model.id if self.application.model is not None else None
|
||||
model_id = self.application.model_id
|
||||
model_params_setting = None
|
||||
if model_id is not None:
|
||||
model = QuerySet(Model).filter(id=model_id).first()
|
||||
@ -127,7 +138,7 @@ class ChatInfo:
|
||||
self.chat_record_list.append(chat_record)
|
||||
if not self.debug:
|
||||
if not QuerySet(Chat).filter(id=self.chat_id).exists():
|
||||
Chat(id=self.chat_id, application_id=self.application.id, abstract=chat_record.problem_text[0:1024],
|
||||
Chat(id=self.chat_id, application_id=self.application_id, abstract=chat_record.problem_text[0:1024],
|
||||
chat_user_id=self.chat_user_id, chat_user_type=self.chat_user_type).save()
|
||||
else:
|
||||
QuerySet(Chat).filter(id=self.chat_id).update(update_time=datetime.now())
|
||||
|
||||
@ -10,7 +10,8 @@ from (select application."id"::text,
|
||||
application."user_id",
|
||||
"user"."nick_name" as "nick_name",
|
||||
application."create_time",
|
||||
application."update_time"
|
||||
application."update_time",
|
||||
application."publish_time"
|
||||
from application left join "user" on user_id = "user".id
|
||||
${application_custom_sql}
|
||||
UNION
|
||||
@ -25,6 +26,7 @@ from (select application."id"::text,
|
||||
application_folder."user_id",
|
||||
"user"."nick_name" as "nick_name",
|
||||
application_folder."create_time",
|
||||
application_folder."update_time"
|
||||
application_folder."update_time",
|
||||
null as "publish_time"
|
||||
from application_folder left join "user" on user_id = "user".id ${folder_query_set}) temp
|
||||
${application_query_set}
|
||||
@ -10,7 +10,8 @@ from (select application."id"::text,
|
||||
application."user_id",
|
||||
"user"."nick_name" as "nick_name",
|
||||
application."create_time",
|
||||
application."update_time"
|
||||
application."update_time",
|
||||
application."publish_time"
|
||||
from application left join "user" on user_id = "user".id
|
||||
where application."id" in (select target
|
||||
from workspace_user_resource_permission
|
||||
@ -28,6 +29,7 @@ from (select application."id"::text,
|
||||
application_folder."user_id",
|
||||
"user"."nick_name" as "nick_name",
|
||||
application_folder."create_time",
|
||||
application_folder."update_time"
|
||||
application_folder."update_time",
|
||||
null as "publish_time"
|
||||
from application_folder left join "user" on user_id = "user".id ${folder_query_set}) temp
|
||||
${application_query_set}
|
||||
@ -10,7 +10,8 @@ from (select application."id"::text,
|
||||
application."user_id",
|
||||
"user"."nick_name" as "nick_name",
|
||||
application."create_time",
|
||||
application."update_time"
|
||||
application."update_time",
|
||||
application."publish_time"
|
||||
from application left join "user" on user_id = "user".id
|
||||
where "application".id in (select target
|
||||
from workspace_user_resource_permission
|
||||
@ -41,6 +42,7 @@ from (select application."id"::text,
|
||||
application_folder."user_id",
|
||||
"user"."nick_name" as "nick_name",
|
||||
application_folder."create_time",
|
||||
application_folder."update_time"
|
||||
application_folder."update_time",
|
||||
null as "publish_time"
|
||||
from application_folder left join "user" on user_id = "user".id ${folder_query_set}) temp
|
||||
${application_query_set}
|
||||
@ -15,7 +15,7 @@ urlpatterns = [
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/application_stats', views.ApplicationStats.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/application_key/<str:api_key_id>', views.ApplicationKey.Operate.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/export', views.ApplicationAPI.Export.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/work_flow_version', views.ApplicationVersionView.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/application_version', views.ApplicationVersionView.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/access_token', views.AccessToken.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/add_knowledge', views.ApplicationChatRecordAddKnowledge.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/chat', views.ApplicationChat.as_view()),
|
||||
@ -27,8 +27,8 @@ urlpatterns = [
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/chat/<str:chat_id>/chat_record/<str:chat_record_id>/improve', views.ApplicationChatRecordImprove.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/chat/<str:chat_id>/chat_record/<str:chat_record_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/improve', views.ApplicationChatRecordImproveParagraph.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/chat/<str:chat_id>/chat_record/<str:chat_record_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/paragraph/<str:paragraph_id>/improve', views.ApplicationChatRecordImproveParagraph.Operate.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/work_flow_version/<int:current_page>/<int:page_size>', views.ApplicationVersionView.Page.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/work_flow_version/<str:work_flow_version_id>', views.ApplicationVersionView.Operate.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/application_version/<int:current_page>/<int:page_size>', views.ApplicationVersionView.Page.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/application_version/<str:application_version_id>', views.ApplicationVersionView.Operate.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/open', views.OpenView.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/text_to_speech', views.TextToSpeech.as_view()),
|
||||
path('workspace/<str:workspace_id>/application/<str:application_id>/speech_to_text', views.SpeechToText.as_view()),
|
||||
|
||||
@ -132,7 +132,8 @@ class ApplicationAPI(APIView):
|
||||
@has_permissions(PermissionConstants.APPLICATION_EXPORT.get_workspace_application_permission(),
|
||||
PermissionConstants.APPLICATION_EXPORT.get_workspace_permission_workspace_manage_role(),
|
||||
ViewPermission([RoleConstants.USER.get_workspace_role()],
|
||||
[PermissionConstants.APPLICATION.get_workspace_application_permission()],CompareConstants.AND),
|
||||
[PermissionConstants.APPLICATION.get_workspace_application_permission()],
|
||||
CompareConstants.AND),
|
||||
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
|
||||
@log(menu='Application', operate="Export Application",
|
||||
get_operation_object=lambda r, k: get_application_operation_object(k.get('application_id')),
|
||||
@ -227,7 +228,7 @@ class ApplicationAPI(APIView):
|
||||
summary=_("Publishing an application"),
|
||||
operation_id=_("Publishing an application"), # type: ignore
|
||||
parameters=ApplicationOperateAPI.get_parameters(),
|
||||
request=ApplicationEditAPI.get_request(),
|
||||
request=None,
|
||||
responses=result.DefaultResultSerializer,
|
||||
tags=[_('Application')] # type: ignore
|
||||
)
|
||||
|
||||
@ -89,11 +89,11 @@ class ApplicationVersionView(APIView):
|
||||
[PermissionConstants.APPLICATION.get_workspace_application_permission()],
|
||||
CompareConstants.AND),
|
||||
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
|
||||
def get(self, request: Request, workspace_id: str, application_id: str, work_flow_version_id: str):
|
||||
def get(self, request: Request, workspace_id: str, application_id: str, application_version_id: str):
|
||||
return result.success(
|
||||
ApplicationVersionSerializer.Operate(
|
||||
data={'user_id': request.user, 'workspace_id': workspace_id,
|
||||
'application_id': application_id, 'work_flow_version_id': work_flow_version_id}).one())
|
||||
'application_id': application_id, 'application_version_id': application_version_id}).one())
|
||||
|
||||
@extend_schema(
|
||||
methods=['PUT'],
|
||||
@ -114,10 +114,10 @@ class ApplicationVersionView(APIView):
|
||||
@log(menu='Application', operate="Modify application version information",
|
||||
get_operation_object=lambda r, k: get_application_operation_object(k.get('application_id')),
|
||||
)
|
||||
def put(self, request: Request, workspace_id: str, application_id: str, work_flow_version_id: str):
|
||||
def put(self, request: Request, workspace_id: str, application_id: str, application_version_id: str):
|
||||
return result.success(
|
||||
ApplicationVersionSerializer.Operate(
|
||||
data={'application_id': application_id, 'workspace_id': workspace_id,
|
||||
'work_flow_version_id': work_flow_version_id,
|
||||
'application_version_id': application_version_id,
|
||||
'user_id': request.user.id}).edit(
|
||||
request.data))
|
||||
|
||||
@ -25,8 +25,8 @@ from application.chat_pipeline.step.search_dataset_step.impl.base_search_dataset
|
||||
from application.flow.common import Answer, Workflow
|
||||
from application.flow.i_step_node import WorkFlowPostHandler
|
||||
from application.flow.workflow_manage import WorkflowManage
|
||||
from application.models import Application, ApplicationTypeChoices, WorkFlowVersion, ApplicationKnowledgeMapping, \
|
||||
ChatUserType, ApplicationChatUserStats, ApplicationAccessToken, ChatRecord, Chat
|
||||
from application.models import Application, ApplicationTypeChoices, ApplicationKnowledgeMapping, \
|
||||
ChatUserType, ApplicationChatUserStats, ApplicationAccessToken, ChatRecord, Chat, ApplicationVersion
|
||||
from application.serializers.application import ApplicationOperateSerializer
|
||||
from application.serializers.common import ChatInfo
|
||||
from common.exception.app_exception import AppApiException, AppChatNumOutOfBoundsFailed, ChatException
|
||||
@ -124,7 +124,7 @@ class ChatSerializers(serializers.Serializer):
|
||||
|
||||
def is_valid_chat_id(self, chat_info: ChatInfo):
|
||||
if self.data.get('application_id') is not None and self.data.get('application_id') != str(
|
||||
chat_info.application.id):
|
||||
chat_info.application_id):
|
||||
raise ChatException(500, _("Conversation does not exist"))
|
||||
|
||||
def is_valid_intraday_access_num(self):
|
||||
@ -148,10 +148,10 @@ class ChatSerializers(serializers.Serializer):
|
||||
|
||||
def is_valid_application_simple(self, *, chat_info: ChatInfo, raise_exception=False):
|
||||
self.is_valid_intraday_access_num()
|
||||
model = chat_info.application.model
|
||||
if model is None:
|
||||
model_id = chat_info.application.model_id
|
||||
if model_id is None:
|
||||
return chat_info
|
||||
model = QuerySet(Model).filter(id=model.id).first()
|
||||
model = QuerySet(Model).filter(id=model_id).first()
|
||||
if model is None:
|
||||
return chat_info
|
||||
if model.status == Status.ERROR:
|
||||
@ -226,10 +226,7 @@ class ChatSerializers(serializers.Serializer):
|
||||
if chat_record_id is not None:
|
||||
chat_record = self.get_chat_record(chat_info, chat_record_id)
|
||||
history_chat_record = [r for r in chat_info.chat_record_list if str(r.id) != chat_record_id]
|
||||
if not debug:
|
||||
work_flow = chat_info.work_flow_version.work_flow
|
||||
else:
|
||||
work_flow = chat_info.application.work_flow
|
||||
work_flow = chat_info.application.work_flow
|
||||
work_flow_manage = WorkflowManage(Workflow.new_instance(work_flow),
|
||||
{'history_chat_record': history_chat_record, 'question': message,
|
||||
'chat_id': chat_info.chat_id, 'chat_record_id': str(
|
||||
@ -252,6 +249,7 @@ class ChatSerializers(serializers.Serializer):
|
||||
super().is_valid(raise_exception=True)
|
||||
ChatMessageSerializers(data=instance).is_valid(raise_exception=True)
|
||||
chat_info = self.get_chat_info()
|
||||
chat_info.get_application()
|
||||
self.is_valid_chat_id(chat_info)
|
||||
if chat_info.application.type == ApplicationTypeChoices.SIMPLE:
|
||||
self.is_valid_application_simple(raise_exception=True, chat_info=chat_info)
|
||||
@ -301,14 +299,13 @@ class ChatSerializers(serializers.Serializer):
|
||||
return chat_info
|
||||
|
||||
def re_open_chat_work_flow(self, chat_id, application):
|
||||
work_flow_version = QuerySet(WorkFlowVersion).filter(application_id=application.id).order_by(
|
||||
application_version = QuerySet(ApplicationVersion).filter(application_id=application.id).order_by(
|
||||
'-create_time')[0:1].first()
|
||||
if work_flow_version is None:
|
||||
if application_version is None:
|
||||
raise ChatException(500, _("The application has not been published. Please use it after publishing."))
|
||||
|
||||
chat_info = ChatInfo(chat_id, self.data.get('chat_user_id'), self.data.get('chat_user_type'), [], [],
|
||||
application.id,
|
||||
application, work_flow_version)
|
||||
application.id)
|
||||
chat_record_list = list(QuerySet(ChatRecord).filter(chat_id=chat_id).order_by('-create_time')[0:5])
|
||||
chat_record_list.sort(key=lambda r: r.create_time)
|
||||
for chat_record in chat_record_list:
|
||||
@ -349,18 +346,16 @@ class OpenChatSerializers(serializers.Serializer):
|
||||
chat_user_type = self.data.get("chat_user_type")
|
||||
debug = self.data.get("debug")
|
||||
chat_id = str(uuid.uuid7())
|
||||
work_flow_version = None
|
||||
if not debug:
|
||||
work_flow_version = QuerySet(WorkFlowVersion).filter(application_id=application_id).order_by(
|
||||
application_version = QuerySet(ApplicationVersion).filter(application_id=application_id).order_by(
|
||||
'-create_time')[0:1].first()
|
||||
if work_flow_version is None:
|
||||
if application_version is None:
|
||||
raise AppApiException(500,
|
||||
gettext(
|
||||
"The application has not been published. Please use it after publishing."))
|
||||
ChatInfo(chat_id, chat_user_id, chat_user_type, [],
|
||||
[],
|
||||
application_id,
|
||||
application, work_flow_version, debug).set_cache()
|
||||
application_id, debug).set_cache()
|
||||
return chat_id
|
||||
|
||||
def open_simple(self, application):
|
||||
@ -378,7 +373,7 @@ class OpenChatSerializers(serializers.Serializer):
|
||||
knowledge_id__in=knowledge_id_list,
|
||||
is_active=False)],
|
||||
application_id,
|
||||
application, debug=debug).set_cache()
|
||||
debug=debug).set_cache()
|
||||
return chat_id
|
||||
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.models import ApplicationAccessToken, ChatUserType, Application, ApplicationTypeChoices, \
|
||||
WorkFlowVersion
|
||||
ApplicationVersion
|
||||
from application.serializers.application import ApplicationSerializerModel
|
||||
from common.auth.common import ChatUserToken, ChatAuthentication
|
||||
from common.constants.authentication_type import AuthenticationType
|
||||
@ -79,6 +79,25 @@ class AuthProfileSerializer(serializers.Serializer):
|
||||
class ApplicationProfileSerializer(serializers.Serializer):
|
||||
application_id = serializers.UUIDField(required=True, label=_("Application ID"))
|
||||
|
||||
@staticmethod
|
||||
def reset_application(application, application_version):
|
||||
update_field_dict = {
|
||||
'application_name': 'name', 'desc': 'desc', 'prologue': 'prologue', 'dialogue_number': 'dialogue_number',
|
||||
'user_id': 'user_id', 'model_id': 'model_id', 'knowledge_setting': 'knowledge_setting',
|
||||
'model_setting': 'model_setting', 'model_params_setting': 'model_params_setting',
|
||||
'tts_model_params_setting': 'tts_model_params_setting',
|
||||
'problem_optimization': 'problem_optimization', 'icon': 'icon', 'work_flow': 'work_flow',
|
||||
'problem_optimization_prompt': 'problem_optimization_prompt', 'tts_model_id': 'tts_model_id',
|
||||
'stt_model_id': 'stt_model_id', 'tts_model_enable': 'tts_model_enable',
|
||||
'stt_model_enable': 'stt_model_enable', 'tts_type': 'tts_type',
|
||||
'tts_autoplay': 'tts_autoplay', 'stt_autosend': 'stt_autosend', 'file_upload_enable': 'file_upload_enable',
|
||||
'file_upload_setting': 'file_upload_setting'
|
||||
}
|
||||
for (version_field, app_field) in update_field_dict.items():
|
||||
_v = getattr(application_version, version_field)
|
||||
if _v:
|
||||
setattr(application, app_field, _v)
|
||||
|
||||
def profile(self, with_valid=True):
|
||||
if with_valid:
|
||||
self.is_valid()
|
||||
@ -88,12 +107,10 @@ class ApplicationProfileSerializer(serializers.Serializer):
|
||||
if application_access_token is None:
|
||||
raise AppUnauthorizedFailed(500, _("Illegal User"))
|
||||
application_setting_model = DatabaseModelManage.get_model('application_setting')
|
||||
if application.type == ApplicationTypeChoices.WORK_FLOW:
|
||||
work_flow_version = QuerySet(WorkFlowVersion).filter(application_id=application.id).order_by(
|
||||
'-create_time')[0:1].first()
|
||||
if work_flow_version is not None:
|
||||
application.work_flow = work_flow_version.work_flow
|
||||
|
||||
application_version = QuerySet(ApplicationVersion).filter(application_id=application.id).order_by(
|
||||
'-create_time')[0:1].first()
|
||||
if application_version is not None:
|
||||
self.reset_application(application, application_version)
|
||||
license_is_valid = cache.get(Cache_Version.SYSTEM.get_key(key='license_is_valid'),
|
||||
version=Cache_Version.SYSTEM.get_version())
|
||||
application_setting_dict = {}
|
||||
|
||||
@ -18,7 +18,7 @@ const getWorkFlowVersion: (
|
||||
application_id: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, loading) => {
|
||||
return get(`${prefix.value}/${application_id}/work_flow_version`, undefined, loading)
|
||||
return get(`${prefix.value}/${application_id}/application_version`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -30,7 +30,7 @@ const getWorkFlowVersionDetail: (
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, application_version_id, loading) => {
|
||||
return get(
|
||||
`${prefix.value}/${application_id}/work_flow_version/${application_version_id}`,
|
||||
`${prefix.value}/${application_id}/application_version/${application_version_id}`,
|
||||
undefined,
|
||||
loading,
|
||||
)
|
||||
@ -45,7 +45,7 @@ const putWorkFlowVersion: (
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, application_version_id, data, loading) => {
|
||||
return put(
|
||||
`${prefix.value}/${application_id}/work_flow_version/${application_version_id}`,
|
||||
`${prefix.value}/${application_id}/application_version/${application_version_id}`,
|
||||
data,
|
||||
undefined,
|
||||
loading,
|
||||
|
||||
@ -114,7 +114,8 @@ export default {
|
||||
},
|
||||
},
|
||||
buttons: {
|
||||
publish: '保存并发布',
|
||||
save: '保存',
|
||||
publish: '发布',
|
||||
addModel: '添加模型',
|
||||
},
|
||||
|
||||
|
||||
@ -281,7 +281,10 @@ const publish = () => {
|
||||
return
|
||||
}
|
||||
applicationApi
|
||||
.publish(id, { work_flow: workflow }, loading)
|
||||
.putApplication(id, { work_flow: workflow }, loading)
|
||||
.then((ok) => {
|
||||
return applicationApi.publish(id, {}, loading)
|
||||
})
|
||||
.then((ok: any) => {
|
||||
detail.value.name = ok.data.name
|
||||
MsgSuccess(t('views.applicationWorkflow.tip.publicSuccess'))
|
||||
|
||||
@ -4,14 +4,24 @@
|
||||
<h3>
|
||||
{{ $t('common.setting') }}
|
||||
</h3>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submit(applicationFormRef)"
|
||||
:disabled="loading"
|
||||
v-if="permissionPrecise.edit(id)"
|
||||
>
|
||||
{{ $t('views.application.buttons.publish') }}
|
||||
</el-button>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submit(applicationFormRef)"
|
||||
:disabled="loading"
|
||||
v-if="permissionPrecise.edit(id)"
|
||||
>
|
||||
{{ $t('views.application.buttons.save') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="publish(applicationFormRef)"
|
||||
:disabled="loading"
|
||||
v-if="permissionPrecise.edit(id)"
|
||||
>
|
||||
{{ $t('views.application.buttons.publish') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-card style="--el-card-padding: 0">
|
||||
<el-row v-loading="loading">
|
||||
@ -444,7 +454,7 @@ import { t } from '@/locales'
|
||||
import TTSModeParamSettingDialog from './component/TTSModeParamSettingDialog.vue'
|
||||
import ReasoningParamSettingDialog from './component/ReasoningParamSettingDialog.vue'
|
||||
import permissionMap from '@/permission'
|
||||
|
||||
import ApplicationAPI from '@/api/application/application'
|
||||
const route = useRoute()
|
||||
|
||||
const apiType = computed<'workspace'>(() => {
|
||||
@ -549,7 +559,18 @@ function submitReasoningDialog(val: any) {
|
||||
...val,
|
||||
}
|
||||
}
|
||||
|
||||
const publish = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.validate().then(() => {
|
||||
return ApplicationAPI.putApplication(id, applicationForm.value, loading)
|
||||
.then((ok) => {
|
||||
return ApplicationAPI.publish(id, {}, loading)
|
||||
})
|
||||
.then((res) => {
|
||||
MsgSuccess(t('common.saveSuccess'))
|
||||
})
|
||||
})
|
||||
}
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate((valid, fields) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user