Skip to content

Commit b0d1a3f

Browse files
committed
feat: Generate Prompt
1 parent ec5c076 commit b0d1a3f

File tree

7 files changed

+139
-5
lines changed

7 files changed

+139
-5
lines changed

apps/application/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
path('workspace/<str:workspace_id>/application/<str:application_id>/speech_to_text', views.SpeechToText.as_view()),
3535
path('workspace/<str:workspace_id>/application/<str:application_id>/play_demo_text', views.PlayDemoText.as_view()),
3636
path('workspace/<str:workspace_id>/application/<str:application_id>/mcp_tools', views.McpServers.as_view()),
37+
path('workspace/<str:workspace_id>/application/model/<str:model_id>/prompt_generate', views.PromptGenerateView.as_view()),
3738
path('chat_message/<str:chat_id>', views.ChatView.as_view()),
3839

3940
]

apps/application/views/application_chat.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
ApplicationChatExportAPI
1818
from application.models import ChatUserType
1919
from application.serializers.application_chat import ApplicationChatQuerySerializers
20-
from chat.api.chat_api import ChatAPI
20+
from chat.api.chat_api import ChatAPI, PromptGenerateAPI
2121
from chat.api.chat_authentication_api import ChatOpenAPI
22-
from chat.serializers.chat import OpenChatSerializers, ChatSerializers, DebugChatSerializers
22+
from chat.serializers.chat import OpenChatSerializers, ChatSerializers, DebugChatSerializers, PromptGenerateSerializer
2323
from common.auth import TokenAuth
2424
from common.auth.authentication import has_permissions
2525
from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
@@ -144,3 +144,18 @@ class ChatView(APIView):
144144
)
145145
def post(self, request: Request, chat_id: str):
146146
return DebugChatSerializers(data={'chat_id': chat_id}).chat(request.data)
147+
148+
class PromptGenerateView(APIView):
149+
150+
@extend_schema(
151+
methods=['POST'],
152+
description=_("generate prompt"),
153+
summary=_("generate prompt"),
154+
operation_id=_("generate prompt"), # type: ignore
155+
request=PromptGenerateAPI.get_request(),
156+
parameters=PromptGenerateAPI.get_parameters(),
157+
responses=None,
158+
tags=[_('Application')] # type: ignore
159+
)
160+
def post(self, request: Request, workspace_id: str, model_id:str):
161+
return PromptGenerateSerializer(data={'workspace_id': workspace_id, 'model_id': model_id}).generate_prompt(instance=request.data)

apps/chat/api/chat_api.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,35 @@
1010
from drf_spectacular.utils import OpenApiParameter
1111

1212
from application.serializers.application_chat_record import ChatRecordSerializerModel
13-
from chat.serializers.chat import ChatMessageSerializers
13+
from chat.serializers.chat import ChatMessageSerializers, GeneratePromptSerializers
1414
from chat.serializers.chat_record import HistoryChatModel, EditAbstractSerializer
1515
from common.mixins.api_mixin import APIMixin
1616
from common.result import ResultSerializer, ResultPageSerializer, DefaultResultSerializer
1717

1818

19+
class PromptGenerateAPI(APIMixin):
20+
@staticmethod
21+
def get_parameters():
22+
return [OpenApiParameter(
23+
name="workspace_id",
24+
description="工作空间id",
25+
type=OpenApiTypes.STR,
26+
location='path',
27+
required=True,
28+
),
29+
OpenApiParameter(
30+
name="model_id",
31+
description="模型id",
32+
type=OpenApiTypes.STR,
33+
location='path',
34+
required=True,)
35+
]
36+
37+
@staticmethod
38+
def get_request():
39+
return GeneratePromptSerializers
40+
41+
1942
class ChatAPI(APIMixin):
2043
@staticmethod
2144
def get_parameters():

apps/chat/serializers/chat.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
@date:2025/6/9 11:23
77
@desc:
88
"""
9-
9+
import json
1010
from gettext import gettext
1111
from typing import List, Dict
1212

1313
import uuid_utils.compat as uuid
1414
from django.db.models import QuerySet
1515
from django.utils.translation import gettext_lazy as _
16+
from langchain_core.messages import HumanMessage, AIMessage
1617
from rest_framework import serializers
1718

1819
from application.chat_pipeline.pipeline_manage import PipelineManage
@@ -24,6 +25,7 @@
2425
from application.chat_pipeline.step.search_dataset_step.impl.base_search_dataset_step import BaseSearchDatasetStep
2526
from application.flow.common import Answer, Workflow
2627
from application.flow.i_step_node import WorkFlowPostHandler
28+
from application.flow.tools import to_stream_response_simple
2729
from application.flow.workflow_manage import WorkflowManage
2830
from application.models import Application, ApplicationTypeChoices, ApplicationKnowledgeMapping, \
2931
ChatUserType, ApplicationChatUserStats, ApplicationAccessToken, ChatRecord, Chat, ApplicationVersion
@@ -37,7 +39,33 @@
3739
from common.utils.common import flat_map
3840
from knowledge.models import Document, Paragraph
3941
from models_provider.models import Model, Status
42+
from models_provider.tools import get_model_instance_by_model_workspace_id
43+
44+
45+
class ChatMessagesSerializers(serializers.Serializer):
46+
role = serializers.CharField(required=True, label=_("Role"))
47+
content = serializers.CharField(required=True, label=_("Content"))
48+
49+
50+
class GeneratePromptSerializers(serializers.Serializer):
51+
prompt = serializers.CharField(required=True, label=_("Prompt template"))
52+
messages = serializers.ListSerializer(child=ChatMessagesSerializers(), required=True, label=_("Chat context"))
4053

54+
def is_valid(self, *, raise_exception=False):
55+
super().is_valid(raise_exception=True)
56+
messages = self.data.get("messages")
57+
58+
if len(messages) > 30:
59+
raise AppApiException(400, _("Too many messages"))
60+
61+
for index in range(len(messages)):
62+
role = messages[index].get('role')
63+
if role == 'ai' and index % 2 != 1:
64+
raise AppApiException(400, _("Authentication failed. Please verify that the parameters are correct."))
65+
if role == 'user' and index % 2 != 0:
66+
raise AppApiException(400, _("Authentication failed. Please verify that the parameters are correct."))
67+
if role not in ['user', 'ai']:
68+
raise AppApiException(400, _("Authentication failed. Please verify that the parameters are correct."))
4169

4270
class ChatMessageSerializers(serializers.Serializer):
4371
message = serializers.CharField(required=True, label=_("User Questions"))
@@ -113,6 +141,37 @@ def chat(self, instance: dict, base_to_response: BaseToResponse = SystemToRespon
113141
}).chat(instance, base_to_response)
114142

115143

144+
class PromptGenerateSerializer(serializers.Serializer):
145+
workspace_id = serializers.CharField(required=False, label=_('Workspace ID'))
146+
model_id = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("Model"))
147+
148+
def generate_prompt(self, instance: dict, with_valid=True):
149+
if with_valid:
150+
self.is_valid(raise_exception=True)
151+
GeneratePromptSerializers(data=instance).is_valid(raise_exception=True)
152+
workspace_id = self.data.get('workspace_id')
153+
model_id = self.data.get('model_id')
154+
prompt = instance.get('prompt')
155+
messages = instance.get('messages')
156+
157+
message = messages[-1]['content']
158+
q = prompt.replace("{userInput}", message)
159+
messages[-1]['content'] = q
160+
161+
model_exist = QuerySet(Model).filter(workspace_id=workspace_id, id=model_id).exists()
162+
if not model_exist:
163+
raise Exception(_("model does not exists"))
164+
165+
def process():
166+
model = get_model_instance_by_model_workspace_id(model_id=model_id, workspace_id=workspace_id)
167+
168+
for r in model.stream([HumanMessage(content=m.get('content')) if m.get('role') == 'user' else AIMessage(
169+
content=m.get('content')) for m in messages]):
170+
yield 'data: ' + json.dumps({'content': r.content}) + '\n\n'
171+
172+
return to_stream_response_simple(process())
173+
174+
116175
class OpenAIMessage(serializers.Serializer):
117176
content = serializers.CharField(required=True, label=_('content'))
118177
role = serializers.CharField(required=True, label=_('Role'))

apps/locales/en_US/LC_MESSAGES/django.po

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8672,4 +8672,16 @@ msgid "System resources authorization"
86728672
msgstr ""
86738673

86748674
msgid "This folder contains resources that you dont have permission"
8675+
msgstr ""
8676+
8677+
msgid "Authentication failed. Please verify that the parameters are correct"
8678+
msgstr ""
8679+
8680+
msgid "Chat context"
8681+
msgstr ""
8682+
8683+
msgid "Prompt template"
8684+
msgstr ""
8685+
8686+
msgid "generate prompt"
86758687
msgstr ""

apps/locales/zh_CN/LC_MESSAGES/django.po

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8799,3 +8799,15 @@ msgstr "系统资源授权"
87998799

88008800
msgid "This folder contains resources that you dont have permission"
88018801
msgstr "此文件夹包含您没有权限的资源"
8802+
8803+
msgid "Authentication failed. Please verify that the parameters are correct"
8804+
msgstr "认证失败,请检查参数是否正确"
8805+
8806+
msgid "Chat context"
8807+
msgstr "聊天上下文"
8808+
8809+
msgid "Prompt template"
8810+
msgstr "提示词模板"
8811+
8812+
msgid "generate prompt"
8813+
msgstr "生成提示词"

apps/locales/zh_Hant/LC_MESSAGES/django.po

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8798,4 +8798,16 @@ msgid "System resources authorization"
87988798
msgstr "系統資源授權"
87998799

88008800
msgid "This folder contains resources that you dont have permission"
8801-
msgstr "此資料夾包含您沒有許可權的資源"
8801+
msgstr "此資料夾包含您沒有許可權的資源"
8802+
8803+
msgid "Authentication failed. Please verify that the parameters are correct"
8804+
msgstr "認證失敗,請檢查參數是否正確"
8805+
8806+
msgid "Chat context"
8807+
msgstr "聊天上下文"
8808+
8809+
msgid "Prompt template"
8810+
msgstr "提示詞範本"
8811+
8812+
msgid "generate prompt"
8813+
msgstr "生成提示詞"

0 commit comments

Comments
 (0)