2023-10-09 11:03:41 +00:00
|
|
|
|
# coding=utf-8
|
|
|
|
|
|
"""
|
|
|
|
|
|
@project: maxkb
|
|
|
|
|
|
@Author:虎
|
|
|
|
|
|
@file: application.py
|
|
|
|
|
|
@date:2023/9/25 14:24
|
|
|
|
|
|
@desc:
|
|
|
|
|
|
"""
|
2024-07-01 01:45:59 +00:00
|
|
|
|
import datetime
|
|
|
|
|
|
import json
|
2023-10-09 11:03:41 +00:00
|
|
|
|
import uuid
|
|
|
|
|
|
|
|
|
|
|
|
from django.contrib.postgres.fields import ArrayField
|
|
|
|
|
|
from django.db import models
|
2024-01-16 08:46:54 +00:00
|
|
|
|
from langchain.schema import HumanMessage, AIMessage
|
2023-10-09 11:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
from common.mixins.app_model_mixin import AppModelMixin
|
2024-01-16 08:46:54 +00:00
|
|
|
|
from dataset.models.data_set import DataSet
|
2023-11-16 05:16:27 +00:00
|
|
|
|
from setting.models.model_management import Model
|
2023-10-09 11:03:41 +00:00
|
|
|
|
from users.models import User
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-01 01:45:59 +00:00
|
|
|
|
class ApplicationTypeChoices(models.TextChoices):
|
|
|
|
|
|
"""订单类型"""
|
|
|
|
|
|
SIMPLE = 'SIMPLE', '简易'
|
|
|
|
|
|
WORK_FLOW = 'WORK_FLOW', '工作流'
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-01-16 08:46:54 +00:00
|
|
|
|
def get_dataset_setting_dict():
|
2024-04-24 07:03:58 +00:00
|
|
|
|
return {'top_n': 3, 'similarity': 0.6, 'max_paragraph_char_number': 5000, 'search_mode': 'embedding',
|
|
|
|
|
|
'no_references_setting': {
|
|
|
|
|
|
'status': 'ai_questioning',
|
|
|
|
|
|
'value': '{question}'
|
|
|
|
|
|
}}
|
2024-01-16 08:46:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_model_setting_dict():
|
2025-02-08 12:26:53 +00:00
|
|
|
|
return {
|
|
|
|
|
|
'prompt': Application.get_default_model_prompt(),
|
|
|
|
|
|
'no_references_prompt': '{question}',
|
|
|
|
|
|
'reasoning_content_start': '<think>',
|
|
|
|
|
|
'reasoning_content_end': '</think>',
|
|
|
|
|
|
'reasoning_content_enable': False,
|
|
|
|
|
|
}
|
2024-01-16 08:46:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-10-09 11:03:41 +00:00
|
|
|
|
class Application(AppModelMixin):
|
|
|
|
|
|
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
|
|
|
|
|
name = models.CharField(max_length=128, verbose_name="应用名称")
|
2024-03-06 10:15:43 +00:00
|
|
|
|
desc = models.CharField(max_length=512, verbose_name="引用描述", default="")
|
2025-01-22 09:56:59 +00:00
|
|
|
|
prologue = models.CharField(max_length=40960, verbose_name="开场白", default="")
|
2023-11-16 05:16:27 +00:00
|
|
|
|
dialogue_number = models.IntegerField(default=0, verbose_name="会话数量")
|
2023-10-09 11:03:41 +00:00
|
|
|
|
user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
|
2023-12-13 09:14:43 +00:00
|
|
|
|
model = models.ForeignKey(Model, on_delete=models.SET_NULL, db_constraint=False, blank=True, null=True)
|
2024-01-16 08:46:54 +00:00
|
|
|
|
dataset_setting = models.JSONField(verbose_name="数据集参数设置", default=get_dataset_setting_dict)
|
|
|
|
|
|
model_setting = models.JSONField(verbose_name="模型参数相关设置", default=get_model_setting_dict)
|
2024-11-14 02:56:59 +00:00
|
|
|
|
model_params_setting = models.JSONField(verbose_name="模型参数相关设置", default=dict)
|
|
|
|
|
|
tts_model_params_setting = models.JSONField(verbose_name="模型参数相关设置", default=dict)
|
2024-01-16 08:46:54 +00:00
|
|
|
|
problem_optimization = models.BooleanField(verbose_name="问题优化", default=False)
|
2024-04-23 11:03:34 +00:00
|
|
|
|
icon = models.CharField(max_length=256, verbose_name="应用icon", default="/ui/favicon.ico")
|
2024-07-01 01:45:59 +00:00
|
|
|
|
work_flow = models.JSONField(verbose_name="工作流数据", default=dict)
|
|
|
|
|
|
type = models.CharField(verbose_name="应用类型", choices=ApplicationTypeChoices.choices,
|
|
|
|
|
|
default=ApplicationTypeChoices.SIMPLE, max_length=256)
|
2024-09-14 13:48:45 +00:00
|
|
|
|
problem_optimization_prompt = models.CharField(verbose_name="问题优化提示词", max_length=102400, blank=True,
|
|
|
|
|
|
null=True,
|
|
|
|
|
|
default="()里面是用户问题,根据上下文回答揣测用户问题({question}) 要求: 输出一个补全问题,并且放在<data></data>标签中")
|
|
|
|
|
|
tts_model = models.ForeignKey(Model, related_name='tts_model_id', on_delete=models.SET_NULL, db_constraint=False,
|
|
|
|
|
|
blank=True, null=True)
|
|
|
|
|
|
stt_model = models.ForeignKey(Model, related_name='stt_model_id', on_delete=models.SET_NULL, db_constraint=False,
|
|
|
|
|
|
blank=True, null=True)
|
2024-09-04 09:02:15 +00:00
|
|
|
|
tts_model_enable = models.BooleanField(verbose_name="语音合成模型是否启用", default=False)
|
|
|
|
|
|
stt_model_enable = models.BooleanField(verbose_name="语音识别模型是否启用", default=False)
|
2024-09-12 03:03:31 +00:00
|
|
|
|
tts_type = models.CharField(verbose_name="语音播放类型", max_length=20, default="BROWSER")
|
2025-01-03 06:24:21 +00:00
|
|
|
|
tts_autoplay = models.BooleanField(verbose_name="自动播放", default=False)
|
2025-01-06 03:08:57 +00:00
|
|
|
|
stt_autosend = models.BooleanField(verbose_name="自动发送", default=False)
|
2024-10-16 08:43:29 +00:00
|
|
|
|
clean_time = models.IntegerField(verbose_name="清理时间", default=180)
|
2024-11-11 07:48:56 +00:00
|
|
|
|
file_upload_enable = models.BooleanField(verbose_name="文件上传是否启用", default=False)
|
2024-11-14 02:56:59 +00:00
|
|
|
|
file_upload_setting = models.JSONField(verbose_name="文件上传相关设置", default=dict)
|
2024-11-11 07:48:56 +00:00
|
|
|
|
|
2024-01-16 08:46:54 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
|
def get_default_model_prompt():
|
|
|
|
|
|
return ('已知信息:'
|
|
|
|
|
|
'\n{data}'
|
|
|
|
|
|
'\n回答要求:'
|
|
|
|
|
|
'\n- 如果你不知道答案或者没有从获取答案,请回答“没有在知识库中查找到相关信息,建议咨询相关技术支持或参考官方文档进行操作”。'
|
|
|
|
|
|
'\n- 避免提及你是从<data></data>中获得的知识。'
|
|
|
|
|
|
'\n- 请保持答案与<data></data>中描述的一致。'
|
|
|
|
|
|
'\n- 请使用markdown 语法优化答案的格式。'
|
|
|
|
|
|
'\n- <data></data>中的图片链接、链接地址和脚本语言请完整返回。'
|
|
|
|
|
|
'\n- 请使用与问题相同的语言来回答。'
|
|
|
|
|
|
'\n问题:'
|
|
|
|
|
|
'\n{question}')
|
2023-11-16 05:16:27 +00:00
|
|
|
|
|
2023-10-09 11:03:41 +00:00
|
|
|
|
class Meta:
|
|
|
|
|
|
db_table = "application"
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-01 01:45:59 +00:00
|
|
|
|
class WorkFlowVersion(AppModelMixin):
|
|
|
|
|
|
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
|
|
|
|
|
application = models.ForeignKey(Application, on_delete=models.CASCADE)
|
2024-10-23 09:01:19 +00:00
|
|
|
|
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="")
|
2024-07-01 01:45:59 +00:00
|
|
|
|
work_flow = models.JSONField(verbose_name="工作流数据", default=dict)
|
|
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
|
db_table = "application_work_flow_version"
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-10-09 11:03:41 +00:00
|
|
|
|
class ApplicationDatasetMapping(AppModelMixin):
|
2023-11-16 05:16:27 +00:00
|
|
|
|
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
|
|
|
|
|
application = models.ForeignKey(Application, on_delete=models.CASCADE)
|
|
|
|
|
|
dataset = models.ForeignKey(DataSet, on_delete=models.CASCADE)
|
2023-10-09 11:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
|
db_table = "application_dataset_mapping"
|
2023-11-16 05:16:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Chat(AppModelMixin):
|
|
|
|
|
|
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
|
|
|
|
|
application = models.ForeignKey(Application, on_delete=models.CASCADE)
|
2024-04-29 05:35:26 +00:00
|
|
|
|
abstract = models.CharField(max_length=1024, verbose_name="摘要")
|
2024-03-28 08:06:54 +00:00
|
|
|
|
client_id = models.UUIDField(verbose_name="客户端id", default=None, null=True)
|
2024-06-13 07:17:36 +00:00
|
|
|
|
is_deleted = models.BooleanField(verbose_name="", default=False)
|
2023-11-16 05:16:27 +00:00
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
|
db_table = "application_chat"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VoteChoices(models.TextChoices):
|
|
|
|
|
|
"""订单类型"""
|
|
|
|
|
|
UN_VOTE = -1, '未投票'
|
|
|
|
|
|
STAR = 0, '赞同'
|
|
|
|
|
|
TRAMPLE = 1, '反对'
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-01 01:45:59 +00:00
|
|
|
|
class DateEncoder(json.JSONEncoder):
|
|
|
|
|
|
def default(self, obj):
|
|
|
|
|
|
if isinstance(obj, uuid.UUID):
|
|
|
|
|
|
return str(obj)
|
|
|
|
|
|
if isinstance(obj, datetime.datetime):
|
|
|
|
|
|
return obj.strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
else:
|
|
|
|
|
|
return json.JSONEncoder.default(self, obj)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-11-16 05:16:27 +00:00
|
|
|
|
class ChatRecord(AppModelMixin):
|
|
|
|
|
|
"""
|
|
|
|
|
|
对话日志 详情
|
|
|
|
|
|
"""
|
|
|
|
|
|
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
|
|
|
|
|
chat = models.ForeignKey(Chat, on_delete=models.CASCADE)
|
|
|
|
|
|
vote_status = models.CharField(verbose_name='投票', max_length=10, choices=VoteChoices.choices,
|
|
|
|
|
|
default=VoteChoices.UN_VOTE)
|
2024-09-26 05:24:22 +00:00
|
|
|
|
problem_text = models.CharField(max_length=10240, verbose_name="问题")
|
2024-04-29 05:35:26 +00:00
|
|
|
|
answer_text = models.CharField(max_length=40960, verbose_name="答案")
|
2024-11-13 02:37:16 +00:00
|
|
|
|
answer_text_list = ArrayField(verbose_name="改进标注列表",
|
2024-12-03 07:23:53 +00:00
|
|
|
|
base_field=models.JSONField()
|
2024-11-13 02:37:16 +00:00
|
|
|
|
, default=list)
|
2023-11-16 05:16:27 +00:00
|
|
|
|
message_tokens = models.IntegerField(verbose_name="请求token数量", default=0)
|
|
|
|
|
|
answer_tokens = models.IntegerField(verbose_name="响应token数量", default=0)
|
2024-01-16 08:46:54 +00:00
|
|
|
|
const = models.IntegerField(verbose_name="总费用", default=0)
|
2024-07-01 01:45:59 +00:00
|
|
|
|
details = models.JSONField(verbose_name="对话详情", default=dict, encoder=DateEncoder)
|
2023-12-13 06:10:51 +00:00
|
|
|
|
improve_paragraph_id_list = ArrayField(verbose_name="改进标注列表",
|
|
|
|
|
|
base_field=models.UUIDField(max_length=128, blank=True)
|
|
|
|
|
|
, default=list)
|
2024-01-16 08:46:54 +00:00
|
|
|
|
run_time = models.FloatField(verbose_name="运行时长", default=0)
|
2023-11-16 05:16:27 +00:00
|
|
|
|
index = models.IntegerField(verbose_name="对话下标")
|
|
|
|
|
|
|
2024-01-16 08:46:54 +00:00
|
|
|
|
def get_human_message(self):
|
|
|
|
|
|
if 'problem_padding' in self.details:
|
|
|
|
|
|
return HumanMessage(content=self.details.get('problem_padding').get('padding_problem_text'))
|
|
|
|
|
|
return HumanMessage(content=self.problem_text)
|
|
|
|
|
|
|
|
|
|
|
|
def get_ai_message(self):
|
|
|
|
|
|
return AIMessage(content=self.answer_text)
|
|
|
|
|
|
|
2024-12-09 03:17:58 +00:00
|
|
|
|
def get_node_details_runtime_node_id(self, runtime_node_id):
|
|
|
|
|
|
return self.details.get(runtime_node_id, None)
|
|
|
|
|
|
|
2023-11-16 05:16:27 +00:00
|
|
|
|
class Meta:
|
|
|
|
|
|
db_table = "application_chat_record"
|