Skip to content

Commit 41dd3c4

Browse files
authored
feat: application view init (#3147)
1 parent da65ce5 commit 41dd3c4

File tree

4 files changed

+257
-1
lines changed

4 files changed

+257
-1
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# coding=utf-8
2+
"""
3+
@project: MaxKB
4+
@Author:虎虎
5+
@file: application.py
6+
@date:2025/5/26 16:59
7+
@desc:
8+
"""
9+
from django.utils.translation import gettext_lazy as _
10+
from drf_spectacular.types import OpenApiTypes
11+
from drf_spectacular.utils import OpenApiParameter
12+
from rest_framework import serializers
13+
14+
from application.serializers.application import ApplicationCreateSerializer
15+
from common.mixins.api_mixin import APIMixin
16+
17+
18+
class ApplicationCreateRequest(ApplicationCreateSerializer.SimplateRequest):
19+
work_flow = serializers.DictField(required=True, label=_("Workflow Objects"))
20+
21+
22+
class ApplicationCreateAPI(APIMixin):
23+
@staticmethod
24+
def get_parameters():
25+
return [
26+
OpenApiParameter(
27+
name="workspace_id",
28+
description="工作空间id",
29+
type=OpenApiTypes.STR,
30+
location='path',
31+
required=True,
32+
)
33+
]
34+
35+
@staticmethod
36+
def get_request():
37+
return ApplicationCreateRequest
38+
39+
@staticmethod
40+
def get_response():
41+
return FolderCreateResponse
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# coding=utf-8
2+
"""
3+
@project: MaxKB
4+
@Author:虎虎
5+
@file: application.py
6+
@date:2025/5/26 17:03
7+
@desc:
8+
"""
9+
import re
10+
from typing import Dict
11+
12+
import uuid_utils.compat as uuid
13+
from django.core import validators
14+
from django.db import models
15+
from django.db.models import QuerySet
16+
from django.utils.translation import gettext_lazy as _
17+
from rest_framework import serializers
18+
19+
from application.models.application import Application, ApplicationTypeChoices
20+
from common.exception.app_exception import AppApiException
21+
from knowledge.models import Knowledge
22+
from models_provider.models import Model
23+
24+
25+
class NoReferencesChoices(models.TextChoices):
26+
"""订单类型"""
27+
ai_questioning = 'ai_questioning', 'ai回答'
28+
designated_answer = 'designated_answer', '指定回答'
29+
30+
31+
class NoReferencesSetting(serializers.Serializer):
32+
status = serializers.ChoiceField(required=True, choices=NoReferencesChoices.choices,
33+
label=_("No reference status"))
34+
value = serializers.CharField(required=True, label=_("Prompt word"))
35+
36+
37+
class KnowledgeSettingSerializer(serializers.Serializer):
38+
top_n = serializers.FloatField(required=True, max_value=10000, min_value=1,
39+
label=_("Reference segment number"))
40+
similarity = serializers.FloatField(required=True, max_value=1, min_value=0,
41+
label=_("Acquaintance"))
42+
max_paragraph_char_number = serializers.IntegerField(required=True, min_value=500, max_value=100000,
43+
label=_("Maximum number of quoted characters"))
44+
search_mode = serializers.CharField(required=True, validators=[
45+
validators.RegexValidator(regex=re.compile("^embedding|keywords|blend$"),
46+
message=_("The type only supports embedding|keywords|blend"), code=500)
47+
], label=_("Retrieval Mode"))
48+
49+
no_references_setting = NoReferencesSetting(required=True,
50+
label=_("Segment settings not referenced"))
51+
52+
53+
class ModelKnowledgeAssociation(serializers.Serializer):
54+
user_id = serializers.UUIDField(required=True, label=_("User ID"))
55+
model_id = serializers.CharField(required=False, allow_null=True, allow_blank=True,
56+
label=_("Model id"))
57+
Knowledge_id_list = serializers.ListSerializer(required=False, child=serializers.UUIDField(required=True,
58+
label=_(
59+
"Knowledge base id")),
60+
label=_("Knowledge Base List"))
61+
62+
def is_valid(self, *, raise_exception=True):
63+
super().is_valid(raise_exception=True)
64+
model_id = self.data.get('model_id')
65+
user_id = self.data.get('user_id')
66+
if model_id is not None and len(model_id) > 0:
67+
if not QuerySet(Model).filter(id=model_id).exists():
68+
raise AppApiException(500, f'{_("Model does not exist")}{model_id}】')
69+
knowledge_id_list = list(set(self.data.get('knowledge_id_list')))
70+
exist_knowledge_id_list = [str(knowledge.id) for knowledge in
71+
QuerySet(Knowledge).filter(id__in=knowledge_id_list, user_id=user_id)]
72+
for knowledge_id in knowledge_id_list:
73+
if not exist_knowledge_id_list.__contains__(knowledge_id):
74+
raise AppApiException(500, f'{_("The knowledge base id does not exist")}{knowledge_id}】')
75+
76+
77+
class ModelSettingSerializer(serializers.Serializer):
78+
prompt = serializers.CharField(required=False, allow_null=True, allow_blank=True, max_length=102400,
79+
label=_("Prompt word"))
80+
system = serializers.CharField(required=False, allow_null=True, allow_blank=True, max_length=102400,
81+
label=_("Role prompts"))
82+
no_references_prompt = serializers.CharField(required=True, max_length=102400, allow_null=True, allow_blank=True,
83+
label=_("No citation segmentation prompt"))
84+
reasoning_content_enable = serializers.BooleanField(required=False,
85+
label=_("Thinking process switch"))
86+
reasoning_content_start = serializers.CharField(required=False, allow_null=True, default="<think>",
87+
allow_blank=True, max_length=256,
88+
trim_whitespace=False,
89+
label=_("The thinking process begins to mark"))
90+
reasoning_content_end = serializers.CharField(required=False, allow_null=True, allow_blank=True, default="</think>",
91+
max_length=256,
92+
trim_whitespace=False,
93+
label=_("End of thinking process marker"))
94+
95+
96+
class ApplicationCreateSerializer(serializers.Serializer):
97+
class WorkflowRequest(serializers.Serializer):
98+
name = serializers.CharField(required=True, max_length=64, min_length=1,
99+
label=_("Application Name"))
100+
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True,
101+
max_length=256, min_length=1,
102+
label=_("Application Description"))
103+
work_flow = serializers.DictField(required=True, label=_("Workflow Objects"))
104+
prologue = serializers.CharField(required=False, allow_null=True, allow_blank=True, max_length=102400,
105+
label=_("Opening remarks"))
106+
107+
@staticmethod
108+
def to_application_model(user_id: str, application: Dict):
109+
default_workflow = application.get('work_flow')
110+
for node in default_workflow.get('nodes'):
111+
if node.get('id') == 'base-node':
112+
node.get('properties')['node_data']['desc'] = application.get('desc')
113+
node.get('properties')['node_data']['name'] = application.get('name')
114+
node.get('properties')['node_data']['prologue'] = application.get('prologue')
115+
return Application(id=uuid.uuid7(),
116+
name=application.get('name'),
117+
desc=application.get('desc'),
118+
prologue="",
119+
dialogue_number=0,
120+
user_id=user_id, model_id=None,
121+
knowledge_setting={},
122+
model_setting={},
123+
problem_optimization=False,
124+
type=ApplicationTypeChoices.WORK_FLOW,
125+
stt_model_enable=application.get('stt_model_enable', False),
126+
stt_model_id=application.get('stt_model', None),
127+
tts_model_id=application.get('tts_model', None),
128+
tts_model_enable=application.get('tts_model_enable', False),
129+
tts_model_params_setting=application.get('tts_model_params_setting', {}),
130+
tts_type=application.get('tts_type', None),
131+
file_upload_enable=application.get('file_upload_enable', False),
132+
file_upload_setting=application.get('file_upload_setting', {}),
133+
work_flow=default_workflow
134+
)
135+
136+
class SimplateRequest(serializers.Serializer):
137+
name = serializers.CharField(required=True, max_length=64, min_length=1,
138+
label=_("application name"))
139+
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True,
140+
max_length=256, min_length=1,
141+
label=_("application describe"))
142+
model_id = serializers.CharField(required=False, allow_null=True, allow_blank=True,
143+
label=_("Model"))
144+
dialogue_number = serializers.IntegerField(required=True,
145+
min_value=0,
146+
max_value=1024,
147+
label=_("Historical chat records"))
148+
prologue = serializers.CharField(required=False, allow_null=True, allow_blank=True, max_length=102400,
149+
label=_("Opening remarks"))
150+
knowledge_id_list = serializers.ListSerializer(required=False, child=serializers.UUIDField(required=True),
151+
allow_null=True,
152+
label=_("Related Knowledge Base"))
153+
# 数据集相关设置
154+
knowledge_setting = KnowledgeSettingSerializer(required=True)
155+
# 模型相关设置
156+
model_setting = ModelSettingSerializer(required=True)
157+
# 问题补全
158+
problem_optimization = serializers.BooleanField(required=True,
159+
label=_("Question completion"))
160+
problem_optimization_prompt = serializers.CharField(required=False, max_length=102400,
161+
label=_("Question completion prompt"))
162+
# 应用类型
163+
type = serializers.CharField(required=True, label=_("Application Type"),
164+
validators=[
165+
validators.RegexValidator(regex=re.compile("^SIMPLE|WORK_FLOW$"),
166+
message=_(
167+
"Application type only supports SIMPLE|WORK_FLOW"),
168+
code=500)
169+
]
170+
)
171+
model_params_setting = serializers.DictField(required=False,
172+
label=_('Model parameters'))
173+
174+
def is_valid(self, *, user_id=None, raise_exception=False):
175+
super().is_valid(raise_exception=True)
176+
ModelKnowledgeAssociation(data={'user_id': user_id, 'model_id': self.data.get('model_id'),
177+
'knowledge_id_list': self.data.get('knowledge_id_list')}).is_valid()
178+
179+
180+
class ApplicationSerializer(serializers.Serializer):
181+
def insert(self):
182+
pass
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# coding=utf-8
2+
"""
3+
@project: MaxKB
4+
@Author:虎虎
5+
@file: application.py
6+
@date:2025/5/26 16:51
7+
@desc:
8+
"""
9+
from django.utils.translation import gettext_lazy as _
10+
from drf_spectacular.utils import extend_schema
11+
from rest_framework.request import Request
12+
from rest_framework.views import APIView
13+
14+
from application.api.application_api import ApplicationCreateAPI
15+
from application.serializers.application import ApplicationSerializer
16+
from common import result
17+
18+
19+
class Application(APIView):
20+
21+
@extend_schema(
22+
methods=['POST'],
23+
description=_('Create an application'),
24+
summary=_('Create an application'),
25+
operation_id=_('Create an application'), # type: ignore
26+
parameters=ApplicationCreateAPI.get_parameters(),
27+
request=ApplicationCreateAPI.get_request(),
28+
responses=ApplicationCreateAPI.get_response(),
29+
tags=[_('Application')] # type: ignore
30+
)
31+
def post(self, request: Request):
32+
return result.success(ApplicationSerializer.insert(request.data))

apps/maxkb/settings/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
'common',
4545
'system_manage',
4646
'models_provider',
47-
'django_celery_beat'
47+
'django_celery_beat',
48+
'application'
4849
]
4950

5051
MIDDLEWARE = [

0 commit comments

Comments
 (0)