Skip to content

Commit c50da4e

Browse files
committed
refactor: 应用设置中配置语音输入和播放
1 parent 38565af commit c50da4e

File tree

9 files changed

+526
-13
lines changed

9 files changed

+526
-13
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Generated by Django 4.2.15 on 2024-09-05 14:35
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('setting', '0006_alter_model_status'),
11+
('application', '0011_application_model_params_setting'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='application',
17+
name='stt_model',
18+
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stt_model_id', to='setting.model'),
19+
),
20+
migrations.AddField(
21+
model_name='application',
22+
name='stt_model_enable',
23+
field=models.BooleanField(default=False, verbose_name='语音识别模型是否启用'),
24+
),
25+
migrations.AddField(
26+
model_name='application',
27+
name='tts_model',
28+
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tts_model_id', to='setting.model'),
29+
),
30+
migrations.AddField(
31+
model_name='application',
32+
name='tts_model_enable',
33+
field=models.BooleanField(default=False, verbose_name='语音合成模型是否启用'),
34+
),
35+
]

apps/application/models/application.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ class Application(AppModelMixin):
5454
work_flow = models.JSONField(verbose_name="工作流数据", default=dict)
5555
type = models.CharField(verbose_name="应用类型", choices=ApplicationTypeChoices.choices,
5656
default=ApplicationTypeChoices.SIMPLE, max_length=256)
57+
tts_model = models.ForeignKey(Model, related_name='tts_model_id', on_delete=models.SET_NULL, db_constraint=False, blank=True, null=True)
58+
stt_model = models.ForeignKey(Model, related_name='stt_model_id', on_delete=models.SET_NULL, db_constraint=False, blank=True, null=True)
59+
tts_model_enable = models.BooleanField(verbose_name="语音合成模型是否启用", default=False)
60+
stt_model_enable = models.BooleanField(verbose_name="语音识别模型是否启用", default=False)
5761

5862
@staticmethod
5963
def get_default_model_prompt():

apps/application/serializers/application_serializers.py

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ def list(self, with_valid=True):
516516
@staticmethod
517517
def reset_application(application: Dict):
518518
application['multiple_rounds_dialogue'] = True if application.get('dialogue_number') > 0 else False
519-
del application['dialogue_number']
519+
520520
if 'dataset_setting' in application:
521521
application['dataset_setting'] = {'search_mode': 'embedding', 'no_references_setting': {
522522
'status': 'ai_questioning',
@@ -711,21 +711,39 @@ def edit(self, instance: Dict, with_valid=True):
711711
raise AppApiException(500, "模型不存在")
712712
if not model.is_permission(application.user_id):
713713
raise AppApiException(500, f"沒有权限使用该模型:{model.name}")
714+
if instance.get('stt_model_id') is None or len(instance.get('stt_model_id')) == 0:
715+
application.stt_model_id = None
716+
else:
717+
model = QuerySet(Model).filter(
718+
id=instance.get('stt_model_id')).first()
719+
if model is None:
720+
raise AppApiException(500, "模型不存在")
721+
if not model.is_permission(application.user_id):
722+
raise AppApiException(500, f"沒有权限使用该模型:{model.name}")
723+
if instance.get('tts_model_id') is None or len(instance.get('tts_model_id')) == 0:
724+
application.tts_model_id = None
725+
else:
726+
model = QuerySet(Model).filter(
727+
id=instance.get('tts_model_id')).first()
728+
if model is None:
729+
raise AppApiException(500, "模型不存在")
730+
if not model.is_permission(application.user_id):
731+
raise AppApiException(500, f"沒有权限使用该模型:{model.name}")
714732
if 'work_flow' in instance:
715733
# 当前用户可修改关联的知识库列表
716734
application_dataset_id_list = [str(dataset_dict.get('id')) for dataset_dict in
717735
self.list_dataset(with_valid=False)]
718736
self.update_reverse_search_node(instance.get('work_flow'), application_dataset_id_list)
737+
# 找到语音配置相关
738+
self.get_work_flow_model(instance)
719739

720740
update_keys = ['name', 'desc', 'model_id', 'multiple_rounds_dialogue', 'prologue', 'status',
721-
'dataset_setting', 'model_setting', 'problem_optimization',
741+
'dataset_setting', 'model_setting', 'problem_optimization', 'dialogue_number',
742+
'stt_model_id', 'tts_model_id', 'tts_model_enable', 'stt_model_enable',
722743
'api_key_is_active', 'icon', 'work_flow', 'model_params_setting']
723744
for update_key in update_keys:
724745
if update_key in instance and instance.get(update_key) is not None:
725-
if update_key == 'multiple_rounds_dialogue':
726-
application.__setattr__('dialogue_number', 0 if not instance.get(update_key) else 3)
727-
else:
728-
application.__setattr__(update_key, instance.get(update_key))
746+
application.__setattr__(update_key, instance.get(update_key))
729747
application.save()
730748

731749
if 'dataset_id_list' in instance:
@@ -825,6 +843,27 @@ def save_other_config(self, data):
825843

826844
application.save()
827845

846+
@staticmethod
847+
def get_work_flow_model(instance):
848+
nodes = instance.get('work_flow')['nodes']
849+
for node in nodes:
850+
if node['id'] == 'base-node':
851+
instance['stt_model_id'] = node['properties']['node_data']['stt_model_id']
852+
instance['tts_model_id'] = node['properties']['node_data']['tts_model_id']
853+
instance['stt_model_enable'] = node['properties']['node_data']['stt_model_enable']
854+
instance['tts_model_enable'] = node['properties']['node_data']['tts_model_enable']
855+
break
856+
857+
def speech_to_text(self, filelist):
858+
# todo 找到模型 mp3转text
859+
print(self.application_id)
860+
print(filelist)
861+
862+
def text_to_speech(self, text):
863+
# todo 找到模型 text转bytes
864+
print(self.application_id)
865+
print(text)
866+
828867
class ApplicationKeySerializerModel(serializers.ModelSerializer):
829868
class Meta:
830869
model = ApplicationApiKey

apps/application/urls.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,8 @@
6363
path(
6464
'application/<str:application_id>/chat/<chat_id>/chat_record/<str:chat_record_id>/dataset/<str:dataset_id>/document_id/<str:document_id>/improve/<str:paragraph_id>',
6565
views.ChatView.ChatRecord.Improve.Operate.as_view(),
66-
name='')
66+
name=''),
67+
path('application/<str:application_id>/<str:model_id>/speech_to_text', views.Application.SpeechToText.as_view(), name='application/audio'),
68+
path('application/<str:application_id>/<str:model_id>/text_to_speech', views.Application.TextToSpeech.as_view(), name='application/audio'),
69+
6770
]

apps/application/views/application_views.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,3 +534,35 @@ def get(self, request: Request, current_page: int, page_size: int):
534534
ApplicationSerializer.Query(
535535
data={**query_params_to_single_dict(request.query_params), 'user_id': request.user.id}).page(
536536
current_page, page_size))
537+
538+
class SpeechToText(APIView):
539+
authentication_classes = [TokenAuth]
540+
541+
@action(methods=['POST'], detail=False)
542+
@has_permissions(ViewPermission([RoleConstants.ADMIN, RoleConstants.USER],
543+
[lambda r, keywords: Permission(group=Group.APPLICATION,
544+
operate=Operate.USE,
545+
dynamic_tag=keywords.get(
546+
'application_id'))],
547+
compare=CompareConstants.AND))
548+
def post(self, request: Request, application_id: str, model_id: str):
549+
return result.success(
550+
ApplicationSerializer.Operate(
551+
data={'application_id': application_id, 'user_id': request.user.id, 'model_id': model_id})
552+
.speech_to_text(request.FILES.getlist('file')[0]))
553+
554+
class TextToSpeech(APIView):
555+
authentication_classes = [TokenAuth]
556+
557+
@action(methods=['POST'], detail=False)
558+
@has_permissions(ViewPermission([RoleConstants.ADMIN, RoleConstants.USER],
559+
[lambda r, keywords: Permission(group=Group.APPLICATION,
560+
operate=Operate.USE,
561+
dynamic_tag=keywords.get(
562+
'application_id'))],
563+
compare=CompareConstants.AND))
564+
def post(self, request: Request, application_id: str, model_id: str):
565+
return result.success(
566+
ApplicationSerializer.Operate(
567+
data={'application_id': application_id, 'user_id': request.user.id, 'model_id': model_id})
568+
.text_to_speech(request.data.get('text')))

ui/src/api/application.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,35 @@ const getApplicationRerankerModel: (
250250
) => Promise<Result<Array<any>>> = (application_id, loading) => {
251251
return get(`${prefix}/${application_id}/model`, { model_type: 'RERANKER' }, loading)
252252
}
253+
254+
/**
255+
* 获取当前用户可使用的模型列表
256+
* @param application_id
257+
* @param loading
258+
* @query { query_text: string, top_number: number, similarity: number }
259+
* @returns
260+
*/
261+
const getApplicationSTTModel: (
262+
application_id: string,
263+
loading?: Ref<boolean>
264+
) => Promise<Result<Array<any>>> = (application_id, loading) => {
265+
return get(`${prefix}/${application_id}/model`, { model_type: 'STT' }, loading)
266+
}
267+
268+
/**
269+
* 获取当前用户可使用的模型列表
270+
* @param application_id
271+
* @param loading
272+
* @query { query_text: string, top_number: number, similarity: number }
273+
* @returns
274+
*/
275+
const getApplicationTTSModel: (
276+
application_id: string,
277+
loading?: Ref<boolean>
278+
) => Promise<Result<Array<any>>> = (application_id, loading) => {
279+
return get(`${prefix}/${application_id}/model`, { model_type: 'TTS' }, loading)
280+
}
281+
253282
/**
254283
* 发布应用
255284
* @param 参数
@@ -324,5 +353,7 @@ export default {
324353
listFunctionLib,
325354
getFunctionLib,
326355
getModelParamsForm,
327-
getApplicationRerankerModel
356+
getApplicationRerankerModel,
357+
getApplicationSTTModel,
358+
getApplicationTTSModel,
328359
}

ui/src/api/type/application.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ interface ApplicationFormType {
1414
type?: string
1515
work_flow?: any
1616
model_params_setting?: any
17+
stt_model_id?: string
18+
tts_model_id?: string
19+
stt_model_enable?: boolean
20+
tts_model_enable?: boolean
1721
}
1822
interface chatType {
1923
id: string

0 commit comments

Comments
 (0)