Merge branch 'main' of https://github.com/maxkb-dev/maxkb
This commit is contained in:
commit
58c0c34b2b
@ -35,12 +35,14 @@ class BaseDocumentExtractNode(IDocumentExtractNode):
|
|||||||
return NodeResult({'content': splitter.join(content)}, {})
|
return NodeResult({'content': splitter.join(content)}, {})
|
||||||
|
|
||||||
def get_details(self, index: int, **kwargs):
|
def get_details(self, index: int, **kwargs):
|
||||||
|
# 不保存content全部内容,因为content内容可能会很大
|
||||||
|
content = (self.context.get('content')[:500] + '...') if len(self.context.get('content')) > 0 else ''
|
||||||
return {
|
return {
|
||||||
'name': self.node.properties.get('stepName'),
|
'name': self.node.properties.get('stepName'),
|
||||||
"index": index,
|
"index": index,
|
||||||
'run_time': self.context.get('run_time'),
|
'run_time': self.context.get('run_time'),
|
||||||
'type': self.node.type,
|
'type': self.node.type,
|
||||||
# 'content': self.context.get('content'), # 不保存content内容,因为content内容可能会很大
|
'content': content,
|
||||||
'status': self.status,
|
'status': self.status,
|
||||||
'err_message': self.err_message,
|
'err_message': self.err_message,
|
||||||
'document_list': self.context.get('document_list')
|
'document_list': self.context.get('document_list')
|
||||||
|
|||||||
@ -154,6 +154,7 @@ def get_post_handler(chat_info: ChatInfo):
|
|||||||
details=manage.get_details(),
|
details=manage.get_details(),
|
||||||
message_tokens=manage.context['message_tokens'],
|
message_tokens=manage.context['message_tokens'],
|
||||||
answer_tokens=manage.context['answer_tokens'],
|
answer_tokens=manage.context['answer_tokens'],
|
||||||
|
answer_text_list=[answer_text],
|
||||||
run_time=manage.context['run_time'],
|
run_time=manage.context['run_time'],
|
||||||
index=len(chat_info.chat_record_list) + 1)
|
index=len(chat_info.chat_record_list) + 1)
|
||||||
chat_info.append_chat_record(chat_record, client_id)
|
chat_info.append_chat_record(chat_record, client_id)
|
||||||
|
|||||||
@ -395,7 +395,8 @@ class ChatRecordSerializerModel(serializers.ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = ChatRecord
|
model = ChatRecord
|
||||||
fields = ['id', 'chat_id', 'vote_status', 'problem_text', 'answer_text',
|
fields = ['id', 'chat_id', 'vote_status', 'problem_text', 'answer_text',
|
||||||
'message_tokens', 'answer_tokens', 'const', 'improve_paragraph_id_list', 'run_time', 'index','answer_text_list',
|
'message_tokens', 'answer_tokens', 'const', 'improve_paragraph_id_list', 'run_time', 'index',
|
||||||
|
'answer_text_list',
|
||||||
'create_time', 'update_time']
|
'create_time', 'update_time']
|
||||||
|
|
||||||
|
|
||||||
@ -457,6 +458,7 @@ class ChatRecordSerializer(serializers.Serializer):
|
|||||||
def reset_chat_record(chat_record):
|
def reset_chat_record(chat_record):
|
||||||
dataset_list = []
|
dataset_list = []
|
||||||
paragraph_list = []
|
paragraph_list = []
|
||||||
|
|
||||||
if 'search_step' in chat_record.details and chat_record.details.get('search_step').get(
|
if 'search_step' in chat_record.details and chat_record.details.get('search_step').get(
|
||||||
'paragraph_list') is not None:
|
'paragraph_list') is not None:
|
||||||
paragraph_list = chat_record.details.get('search_step').get(
|
paragraph_list = chat_record.details.get('search_step').get(
|
||||||
@ -468,6 +470,14 @@ class ChatRecordSerializer(serializers.Serializer):
|
|||||||
row in
|
row in
|
||||||
paragraph_list],
|
paragraph_list],
|
||||||
{}).items()]
|
{}).items()]
|
||||||
|
if len(chat_record.improve_paragraph_id_list) > 0:
|
||||||
|
paragraph_model_list = QuerySet(Paragraph).filter(id__in=chat_record.improve_paragraph_id_list)
|
||||||
|
if len(paragraph_model_list) < len(chat_record.improve_paragraph_id_list):
|
||||||
|
paragraph_model_id_list = [str(p.id) for p in paragraph_model_list]
|
||||||
|
chat_record.improve_paragraph_id_list = list(
|
||||||
|
filter(lambda p_id: paragraph_model_id_list.__contains__(p_id),
|
||||||
|
chat_record.improve_paragraph_id_list))
|
||||||
|
chat_record.save()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
**ChatRecordSerializerModel(chat_record).data,
|
**ChatRecordSerializerModel(chat_record).data,
|
||||||
@ -608,13 +618,11 @@ class ChatRecordSerializer(serializers.Serializer):
|
|||||||
title=instance.get("title") if 'title' in instance else '')
|
title=instance.get("title") if 'title' in instance else '')
|
||||||
problem_text = instance.get('problem_text') if instance.get(
|
problem_text = instance.get('problem_text') if instance.get(
|
||||||
'problem_text') is not None else chat_record.problem_text
|
'problem_text') is not None else chat_record.problem_text
|
||||||
problem = Problem(id=uuid.uuid1(), content=problem_text, dataset_id=dataset_id)
|
problem, _ = Problem.objects.get_or_create(content=problem_text, dataset_id=dataset_id)
|
||||||
problem_paragraph_mapping = ProblemParagraphMapping(id=uuid.uuid1(), dataset_id=dataset_id,
|
problem_paragraph_mapping = ProblemParagraphMapping(id=uuid.uuid1(), dataset_id=dataset_id,
|
||||||
document_id=document_id,
|
document_id=document_id,
|
||||||
problem_id=problem.id,
|
problem_id=problem.id,
|
||||||
paragraph_id=paragraph.id)
|
paragraph_id=paragraph.id)
|
||||||
# 插入问题
|
|
||||||
problem.save()
|
|
||||||
# 插入段落
|
# 插入段落
|
||||||
paragraph.save()
|
paragraph.save()
|
||||||
# 插入关联问题
|
# 插入关联问题
|
||||||
|
|||||||
@ -36,8 +36,9 @@ def update_execute(sql: str, params):
|
|||||||
"""
|
"""
|
||||||
with connection.cursor() as cursor:
|
with connection.cursor() as cursor:
|
||||||
cursor.execute(sql, params)
|
cursor.execute(sql, params)
|
||||||
|
affected_rows = cursor.rowcount
|
||||||
cursor.close()
|
cursor.close()
|
||||||
return None
|
return affected_rows
|
||||||
|
|
||||||
|
|
||||||
def select_list(sql: str, params: List):
|
def select_list(sql: str, params: List):
|
||||||
|
|||||||
@ -10,11 +10,12 @@ import datetime
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
import django.db.models
|
import django.db.models
|
||||||
from django.db import models
|
from django.db import models, transaction
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.db.models.functions import Substr, Reverse
|
from django.db.models.functions import Substr, Reverse
|
||||||
from langchain_core.embeddings import Embeddings
|
from langchain_core.embeddings import Embeddings
|
||||||
@ -168,6 +169,7 @@ class ListenerManagement:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_aggregation_document_status(document_id):
|
def get_aggregation_document_status(document_id):
|
||||||
def aggregation_document_status():
|
def aggregation_document_status():
|
||||||
|
pass
|
||||||
sql = get_file_content(
|
sql = get_file_content(
|
||||||
os.path.join(PROJECT_DIR, "apps", "dataset", 'sql', 'update_document_status_meta.sql'))
|
os.path.join(PROJECT_DIR, "apps", "dataset", 'sql', 'update_document_status_meta.sql'))
|
||||||
native_update({'document_custom_sql': QuerySet(Document).filter(id=document_id)}, sql, with_table_name=True)
|
native_update({'document_custom_sql': QuerySet(Document).filter(id=document_id)}, sql, with_table_name=True)
|
||||||
@ -179,7 +181,8 @@ class ListenerManagement:
|
|||||||
def aggregation_document_status():
|
def aggregation_document_status():
|
||||||
sql = get_file_content(
|
sql = get_file_content(
|
||||||
os.path.join(PROJECT_DIR, "apps", "dataset", 'sql', 'update_document_status_meta.sql'))
|
os.path.join(PROJECT_DIR, "apps", "dataset", 'sql', 'update_document_status_meta.sql'))
|
||||||
native_update({'document_custom_sql': QuerySet(Document).filter(dataset_id=dataset_id)}, sql)
|
native_update({'document_custom_sql': QuerySet(Document).filter(dataset_id=dataset_id)}, sql,
|
||||||
|
with_table_name=True)
|
||||||
|
|
||||||
return aggregation_document_status
|
return aggregation_document_status
|
||||||
|
|
||||||
@ -188,7 +191,7 @@ class ListenerManagement:
|
|||||||
def aggregation_document_status():
|
def aggregation_document_status():
|
||||||
sql = get_file_content(
|
sql = get_file_content(
|
||||||
os.path.join(PROJECT_DIR, "apps", "dataset", 'sql', 'update_document_status_meta.sql'))
|
os.path.join(PROJECT_DIR, "apps", "dataset", 'sql', 'update_document_status_meta.sql'))
|
||||||
native_update({'document_custom_sql': queryset}, sql)
|
native_update({'document_custom_sql': queryset}, sql, with_table_name=True)
|
||||||
|
|
||||||
return aggregation_document_status
|
return aggregation_document_status
|
||||||
|
|
||||||
@ -247,19 +250,23 @@ class ListenerManagement:
|
|||||||
"""
|
"""
|
||||||
if not try_lock('embedding' + str(document_id)):
|
if not try_lock('embedding' + str(document_id)):
|
||||||
return
|
return
|
||||||
max_kb.info(f"开始--->向量化文档:{document_id}")
|
|
||||||
# 批量修改状态为PADDING
|
|
||||||
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id), TaskType.EMBEDDING, State.STARTED)
|
|
||||||
try:
|
try:
|
||||||
# 删除文档向量数据
|
|
||||||
VectorStore.get_embedding_vector().delete_by_document_id(document_id)
|
|
||||||
|
|
||||||
def is_the_task_interrupted():
|
def is_the_task_interrupted():
|
||||||
document = QuerySet(Document).filter(id=document_id).first()
|
document = QuerySet(Document).filter(id=document_id).first()
|
||||||
if document is None or Status(document.status)[TaskType.EMBEDDING] == State.REVOKE:
|
if document is None or Status(document.status)[TaskType.EMBEDDING] == State.REVOKE:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if is_the_task_interrupted():
|
||||||
|
return
|
||||||
|
max_kb.info(f"开始--->向量化文档:{document_id}")
|
||||||
|
# 批量修改状态为PADDING
|
||||||
|
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id), TaskType.EMBEDDING,
|
||||||
|
State.STARTED)
|
||||||
|
|
||||||
|
# 删除文档向量数据
|
||||||
|
VectorStore.get_embedding_vector().delete_by_document_id(document_id)
|
||||||
|
|
||||||
# 根据段落进行向量化处理
|
# 根据段落进行向量化处理
|
||||||
page(QuerySet(Paragraph).filter(document_id=document_id).values('id'), 5,
|
page(QuerySet(Paragraph).filter(document_id=document_id).values('id'), 5,
|
||||||
ListenerManagement.get_embedding_paragraph_apply(embedding_model, is_the_task_interrupted,
|
ListenerManagement.get_embedding_paragraph_apply(embedding_model, is_the_task_interrupted,
|
||||||
|
|||||||
@ -198,4 +198,4 @@ class DocSplitHandle(BaseSplitHandle):
|
|||||||
return self.to_md(doc, image_list, get_image_id_func())
|
return self.to_md(doc, image_list, get_image_id_func())
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
traceback.print_exception(e)
|
traceback.print_exception(e)
|
||||||
return ''
|
return f'{e}'
|
||||||
@ -70,4 +70,4 @@ class HTMLSplitHandle(BaseSplitHandle):
|
|||||||
return html2text(content)
|
return html2text(content)
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
traceback.print_exception(e)
|
traceback.print_exception(e)
|
||||||
return ''
|
return f'{e}'
|
||||||
@ -321,4 +321,4 @@ class PdfSplitHandle(BaseSplitHandle):
|
|||||||
return self.handle_pdf_content(file, pdf_document)
|
return self.handle_pdf_content(file, pdf_document)
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
traceback.print_exception(e)
|
traceback.print_exception(e)
|
||||||
return ''
|
return f'{e}'
|
||||||
@ -57,4 +57,4 @@ class TextSplitHandle(BaseSplitHandle):
|
|||||||
return buffer.decode(detect(buffer)['encoding'])
|
return buffer.decode(detect(buffer)['encoding'])
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
traceback.print_exception(e)
|
traceback.print_exception(e)
|
||||||
return ''
|
return f'{e}'
|
||||||
@ -18,10 +18,11 @@ def page(query_set, page_size, handler, is_the_task_interrupted=lambda: False):
|
|||||||
@param is_the_task_interrupted: 任务是否被中断
|
@param is_the_task_interrupted: 任务是否被中断
|
||||||
@return:
|
@return:
|
||||||
"""
|
"""
|
||||||
|
query = query_set.order_by("id")
|
||||||
count = query_set.count()
|
count = query_set.count()
|
||||||
for i in range(0, ceil(count / page_size)):
|
for i in range(0, ceil(count / page_size)):
|
||||||
if is_the_task_interrupted():
|
if is_the_task_interrupted():
|
||||||
return
|
return
|
||||||
offset = i * page_size
|
offset = i * page_size
|
||||||
paragraph_list = query_set[offset: offset + page_size]
|
paragraph_list = query.all()[offset: offset + page_size]
|
||||||
handler(paragraph_list)
|
handler(paragraph_list)
|
||||||
|
|||||||
@ -7,6 +7,11 @@ import dataset
|
|||||||
from common.event import ListenerManagement
|
from common.event import ListenerManagement
|
||||||
from dataset.models import State, TaskType
|
from dataset.models import State, TaskType
|
||||||
|
|
||||||
|
sql = """
|
||||||
|
UPDATE "document"
|
||||||
|
SET status ="replace"(status, '1', '3')
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def updateDocumentStatus(apps, schema_editor):
|
def updateDocumentStatus(apps, schema_editor):
|
||||||
ParagraphModel = apps.get_model('dataset', 'Paragraph')
|
ParagraphModel = apps.get_model('dataset', 'Paragraph')
|
||||||
@ -43,5 +48,6 @@ class Migration(migrations.Migration):
|
|||||||
name='status',
|
name='status',
|
||||||
field=models.CharField(default=dataset.models.data_set.Status.__str__, max_length=20, verbose_name='状态'),
|
field=models.CharField(default=dataset.models.data_set.Status.__str__, max_length=20, verbose_name='状态'),
|
||||||
),
|
),
|
||||||
|
migrations.RunSQL(sql),
|
||||||
migrations.RunPython(updateDocumentStatus)
|
migrations.RunPython(updateDocumentStatus)
|
||||||
]
|
]
|
||||||
|
|||||||
@ -297,6 +297,9 @@ class DocumentSerializers(ApiMixin, serializers.Serializer):
|
|||||||
ListenerManagement.update_status(QuerySet(Document).filter(id__in=document_id_list),
|
ListenerManagement.update_status(QuerySet(Document).filter(id__in=document_id_list),
|
||||||
TaskType.EMBEDDING,
|
TaskType.EMBEDDING,
|
||||||
State.PENDING)
|
State.PENDING)
|
||||||
|
ListenerManagement.update_status(QuerySet(Paragraph).filter(document_id__in=document_id_list),
|
||||||
|
TaskType.EMBEDDING,
|
||||||
|
State.PENDING)
|
||||||
embedding_by_document_list.delay(document_id_list, model_id)
|
embedding_by_document_list.delay(document_id_list, model_id)
|
||||||
else:
|
else:
|
||||||
update_embedding_dataset_id(pid_list, target_dataset_id)
|
update_embedding_dataset_id(pid_list, target_dataset_id)
|
||||||
@ -613,7 +616,8 @@ class DocumentSerializers(ApiMixin, serializers.Serializer):
|
|||||||
document_id = self.data.get("document_id")
|
document_id = self.data.get("document_id")
|
||||||
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id), TaskType.EMBEDDING,
|
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id), TaskType.EMBEDDING,
|
||||||
State.PENDING)
|
State.PENDING)
|
||||||
ListenerManagement.update_status(QuerySet(Paragraph).filter(document_id=document_id), TaskType.EMBEDDING,
|
ListenerManagement.update_status(QuerySet(Paragraph).filter(document_id=document_id),
|
||||||
|
TaskType.EMBEDDING,
|
||||||
State.PENDING)
|
State.PENDING)
|
||||||
ListenerManagement.get_aggregation_document_status(document_id)()
|
ListenerManagement.get_aggregation_document_status(document_id)()
|
||||||
embedding_model_id = get_embedding_model_id_by_dataset_id(dataset_id=self.data.get('dataset_id'))
|
embedding_model_id = get_embedding_model_id_by_dataset_id(dataset_id=self.data.get('dataset_id'))
|
||||||
@ -708,8 +712,8 @@ class DocumentSerializers(ApiMixin, serializers.Serializer):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def post_embedding(result, document_id, dataset_id):
|
def post_embedding(result, document_id, dataset_id):
|
||||||
model_id = get_embedding_model_id_by_dataset_id(dataset_id)
|
DocumentSerializers.Operate(
|
||||||
embedding_by_document.delay(document_id, model_id)
|
data={'dataset_id': dataset_id, 'document_id': document_id}).refresh()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -907,8 +911,8 @@ class DocumentSerializers(ApiMixin, serializers.Serializer):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def post_embedding(document_list, dataset_id):
|
def post_embedding(document_list, dataset_id):
|
||||||
for document_dict in document_list:
|
for document_dict in document_list:
|
||||||
model_id = get_embedding_model_id_by_dataset_id(dataset_id)
|
DocumentSerializers.Operate(
|
||||||
embedding_by_document.delay(document_dict.get('id'), model_id)
|
data={'dataset_id': dataset_id, 'document_id': document_dict.get('id')}).refresh()
|
||||||
return document_list
|
return document_list
|
||||||
|
|
||||||
@post(post_function=post_embedding)
|
@post(post_function=post_embedding)
|
||||||
|
|||||||
@ -540,8 +540,16 @@ class ParagraphSerializers(ApiMixin, serializers.Serializer):
|
|||||||
if with_valid:
|
if with_valid:
|
||||||
self.is_valid(raise_exception=True)
|
self.is_valid(raise_exception=True)
|
||||||
paragraph_id = self.data.get('paragraph_id')
|
paragraph_id = self.data.get('paragraph_id')
|
||||||
QuerySet(Paragraph).filter(id=paragraph_id).delete()
|
Paragraph.objects.filter(id=paragraph_id).delete()
|
||||||
QuerySet(ProblemParagraphMapping).filter(paragraph_id=paragraph_id).delete()
|
|
||||||
|
problem_id = ProblemParagraphMapping.objects.filter(paragraph_id=paragraph_id).values_list('problem_id',
|
||||||
|
flat=True).first()
|
||||||
|
|
||||||
|
if problem_id is not None:
|
||||||
|
if ProblemParagraphMapping.objects.filter(problem_id=problem_id).count() == 1:
|
||||||
|
Problem.objects.filter(id=problem_id).delete()
|
||||||
|
ProblemParagraphMapping.objects.filter(paragraph_id=paragraph_id).delete()
|
||||||
|
|
||||||
update_document_char_length(self.data.get('document_id'))
|
update_document_char_length(self.data.get('document_id'))
|
||||||
delete_embedding_by_paragraph(paragraph_id)
|
delete_embedding_by_paragraph(paragraph_id)
|
||||||
|
|
||||||
|
|||||||
@ -51,21 +51,28 @@ def get_generate_problem(llm_model, prompt, post_apply=lambda: None, is_the_task
|
|||||||
return generate_problem
|
return generate_problem
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(base=QueueOnce, once={'keys': ['document_id']},
|
def get_is_the_task_interrupted(document_id):
|
||||||
name='celery:generate_related_by_document')
|
|
||||||
def generate_related_by_document_id(document_id, model_id, prompt):
|
|
||||||
try:
|
|
||||||
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id),
|
|
||||||
TaskType.GENERATE_PROBLEM,
|
|
||||||
State.STARTED)
|
|
||||||
llm_model = get_llm_model(model_id)
|
|
||||||
|
|
||||||
def is_the_task_interrupted():
|
def is_the_task_interrupted():
|
||||||
document = QuerySet(Document).filter(id=document_id).first()
|
document = QuerySet(Document).filter(id=document_id).first()
|
||||||
if document is None or Status(document.status)[TaskType.GENERATE_PROBLEM] == State.REVOKE:
|
if document is None or Status(document.status)[TaskType.GENERATE_PROBLEM] == State.REVOKE:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
return is_the_task_interrupted
|
||||||
|
|
||||||
|
|
||||||
|
@celery_app.task(base=QueueOnce, once={'keys': ['document_id']},
|
||||||
|
name='celery:generate_related_by_document')
|
||||||
|
def generate_related_by_document_id(document_id, model_id, prompt):
|
||||||
|
try:
|
||||||
|
is_the_task_interrupted = get_is_the_task_interrupted(document_id)
|
||||||
|
if is_the_task_interrupted():
|
||||||
|
return
|
||||||
|
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id),
|
||||||
|
TaskType.GENERATE_PROBLEM,
|
||||||
|
State.STARTED)
|
||||||
|
llm_model = get_llm_model(model_id)
|
||||||
|
|
||||||
# 生成问题函数
|
# 生成问题函数
|
||||||
generate_problem = get_generate_problem(llm_model, prompt,
|
generate_problem = get_generate_problem(llm_model, prompt,
|
||||||
ListenerManagement.get_aggregation_document_status(
|
ListenerManagement.get_aggregation_document_status(
|
||||||
@ -82,6 +89,12 @@ def generate_related_by_document_id(document_id, model_id, prompt):
|
|||||||
name='celery:generate_related_by_paragraph_list')
|
name='celery:generate_related_by_paragraph_list')
|
||||||
def generate_related_by_paragraph_id_list(document_id, paragraph_id_list, model_id, prompt):
|
def generate_related_by_paragraph_id_list(document_id, paragraph_id_list, model_id, prompt):
|
||||||
try:
|
try:
|
||||||
|
is_the_task_interrupted = get_is_the_task_interrupted(document_id)
|
||||||
|
if is_the_task_interrupted():
|
||||||
|
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id),
|
||||||
|
TaskType.GENERATE_PROBLEM,
|
||||||
|
State.REVOKED)
|
||||||
|
return
|
||||||
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id),
|
ListenerManagement.update_status(QuerySet(Document).filter(id=document_id),
|
||||||
TaskType.GENERATE_PROBLEM,
|
TaskType.GENERATE_PROBLEM,
|
||||||
State.STARTED)
|
State.STARTED)
|
||||||
|
|||||||
@ -102,6 +102,7 @@ def embedding_by_dataset(dataset_id, model_id):
|
|||||||
max_kb.info(f"数据集文档:{[d.name for d in document_list]}")
|
max_kb.info(f"数据集文档:{[d.name for d in document_list]}")
|
||||||
for document in document_list:
|
for document in document_list:
|
||||||
try:
|
try:
|
||||||
|
print(document.id, model_id)
|
||||||
embedding_by_document.delay(document.id, model_id)
|
embedding_by_document.delay(document.id, model_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -32,9 +32,11 @@ CELERY_WORKER_REDIRECT_STDOUTS = True
|
|||||||
CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO"
|
CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO"
|
||||||
CELERY_TASK_SOFT_TIME_LIMIT = 3600
|
CELERY_TASK_SOFT_TIME_LIMIT = 3600
|
||||||
CELERY_WORKER_CANCEL_LONG_RUNNING_TASKS_ON_CONNECTION_LOSS = True
|
CELERY_WORKER_CANCEL_LONG_RUNNING_TASKS_ON_CONNECTION_LOSS = True
|
||||||
|
CELERY_ACKS_LATE = True
|
||||||
|
celery_once_path = os.path.join(celery_data_dir, "celery_once")
|
||||||
CELERY_ONCE = {
|
CELERY_ONCE = {
|
||||||
'backend': 'celery_once.backends.File',
|
'backend': 'celery_once.backends.File',
|
||||||
'settings': {'location': os.path.join(celery_data_dir, "celery_once")}
|
'settings': {'location': celery_once_path}
|
||||||
}
|
}
|
||||||
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
|
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
|
||||||
CELERY_LOG_DIR = os.path.join(PROJECT_DIR, 'logs', 'celery')
|
CELERY_LOG_DIR = os.path.join(PROJECT_DIR, 'logs', 'celery')
|
||||||
|
|||||||
@ -63,11 +63,10 @@
|
|||||||
<span class="color-secondary">{{ f.label }}:</span> {{ f.value }}
|
<span class="color-secondary">{{ f.label }}:</span> {{ f.value }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.document_list?.length > 0">
|
<div v-if="item.document_list?.length > 0">
|
||||||
<p class="mb-8 color-secondary">上传的文档:</p>
|
<p class="mb-8 color-secondary">文档:</p>
|
||||||
|
|
||||||
<el-space wrap>
|
<el-space wrap>
|
||||||
<template v-for="(f, i) in item.document_list" :key="i">
|
<template v-for="(f, i) in item.document_list" :key="i">
|
||||||
{{ f.name }}
|
|
||||||
<el-card
|
<el-card
|
||||||
shadow="never"
|
shadow="never"
|
||||||
style="--el-card-padding: 8px"
|
style="--el-card-padding: 8px"
|
||||||
@ -84,7 +83,7 @@
|
|||||||
</el-space>
|
</el-space>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.image_list?.length > 0">
|
<div v-if="item.image_list?.length > 0">
|
||||||
<p class="mb-8 color-secondary">上传的图片:</p>
|
<p class="mb-8 color-secondary">图片:</p>
|
||||||
|
|
||||||
<el-space wrap>
|
<el-space wrap>
|
||||||
<template v-for="(f, i) in item.image_list" :key="i">
|
<template v-for="(f, i) in item.image_list" :key="i">
|
||||||
@ -219,7 +218,16 @@
|
|||||||
<!-- 文档内容提取 -->
|
<!-- 文档内容提取 -->
|
||||||
<template v-if="item.type === WorkflowType.DocumentExtractNode">
|
<template v-if="item.type === WorkflowType.DocumentExtractNode">
|
||||||
<div class="card-never border-r-4">
|
<div class="card-never border-r-4">
|
||||||
<h5 class="p-8-12">参数输出</h5>
|
<h5 class="p-8-12">
|
||||||
|
参数输出
|
||||||
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
content="每个文档仅支持预览500字"
|
||||||
|
placement="right"
|
||||||
|
>
|
||||||
|
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
|
||||||
|
</el-tooltip>
|
||||||
|
</h5>
|
||||||
<div class="p-8-12 border-t-dashed lighter">
|
<div class="p-8-12 border-t-dashed lighter">
|
||||||
<el-scrollbar height="150">
|
<el-scrollbar height="150">
|
||||||
<MdPreview
|
<MdPreview
|
||||||
|
|||||||
@ -84,14 +84,15 @@
|
|||||||
:on-change="(file: any, fileList: any) => uploadFile(file, fileList)"
|
:on-change="(file: any, fileList: any) => uploadFile(file, fileList)"
|
||||||
>
|
>
|
||||||
<el-tooltip effect="dark" placement="top" popper-class="upload-tooltip-width">
|
<el-tooltip effect="dark" placement="top" popper-class="upload-tooltip-width">
|
||||||
<template #content
|
<template #content>
|
||||||
>上传文件:最多{{
|
<div class="break-all pre-wrap">上传文件:最多{{
|
||||||
props.applicationDetails.file_upload_setting.maxFiles
|
props.applicationDetails.file_upload_setting.maxFiles
|
||||||
}}个,每个文件限制
|
}}个,每个文件限制
|
||||||
{{ props.applicationDetails.file_upload_setting.fileLimit }}MB<br />文件类型:{{
|
{{ props.applicationDetails.file_upload_setting.fileLimit }}MB<br />文件类型:{{
|
||||||
getAcceptList().replace(/\./g, '').replace(/,/g, '、').toUpperCase()
|
getAcceptList().replace(/\./g, '').replace(/,/g, '、').toUpperCase()
|
||||||
}}</template
|
}}
|
||||||
>
|
</div>
|
||||||
|
</template>
|
||||||
<el-button text>
|
<el-button text>
|
||||||
<el-icon><Paperclip /></el-icon>
|
<el-icon><Paperclip /></el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -216,6 +217,9 @@ const getAcceptList = () => {
|
|||||||
accepts = [...accepts, ...videoExtensions]
|
accepts = [...accepts, ...videoExtensions]
|
||||||
}
|
}
|
||||||
// console.log(accepts)
|
// console.log(accepts)
|
||||||
|
if (accepts.length === 0) {
|
||||||
|
return '.请在文件上传配置中选择文件类型'
|
||||||
|
}
|
||||||
return accepts.map((ext: any) => '.' + ext).join(',')
|
return accepts.map((ext: any) => '.' + ext).join(',')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
:key="dynamicsFormRefresh"
|
:key="dynamicsFormRefresh"
|
||||||
v-model="form_data_context"
|
v-model="form_data_context"
|
||||||
:model="form_data_context"
|
:model="form_data_context"
|
||||||
label-position="left"
|
label-position="top"
|
||||||
require-asterisk-position="right"
|
require-asterisk-position="right"
|
||||||
:render_data="inputFieldList"
|
:render_data="inputFieldList"
|
||||||
ref="dynamicsFormRef"
|
ref="dynamicsFormRef"
|
||||||
@ -29,7 +29,7 @@
|
|||||||
v-if="type === 'debug-ai-chat'"
|
v-if="type === 'debug-ai-chat'"
|
||||||
v-model="api_form_data_context"
|
v-model="api_form_data_context"
|
||||||
:model="api_form_data_context"
|
:model="api_form_data_context"
|
||||||
label-position="left"
|
label-position="top"
|
||||||
require-asterisk-position="right"
|
require-asterisk-position="right"
|
||||||
:render_data="apiInputFieldList"
|
:render_data="apiInputFieldList"
|
||||||
ref="dynamicsFormRef2"
|
ref="dynamicsFormRef2"
|
||||||
|
|||||||
@ -538,7 +538,7 @@
|
|||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="scrollbar-height">
|
<div class="scrollbar-height">
|
||||||
<AiChat :applicationDetails="applicationForm"></AiChat>
|
<AiChat :applicationDetails="applicationForm" :type="'debug-ai-chat'"></AiChat>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|||||||
@ -1,51 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-popover placement="top" :width="450" trigger="hover">
|
<el-popover v-model:visible="visible" placement="top" :width="450" trigger="hover">
|
||||||
<template #default>
|
<template #default
|
||||||
<el-row :gutter="3" v-for="status in statusTable" :key="status.type">
|
><StatusTable
|
||||||
<el-col :span="4">{{ taskTypeMap[status.type] }} </el-col>
|
v-if="visible"
|
||||||
<el-col :span="4">
|
:status="status"
|
||||||
<el-text v-if="status.state === State.SUCCESS || status.state === State.REVOKED">
|
:statusMeta="statusMeta"
|
||||||
<el-icon class="success"><SuccessFilled /></el-icon>
|
:taskTypeMap="taskTypeMap"
|
||||||
{{ stateMap[status.state](status.type) }}
|
:stateMap="stateMap"
|
||||||
</el-text>
|
></StatusTable>
|
||||||
<el-text v-else-if="status.state === State.FAILURE">
|
|
||||||
<el-icon class="danger"><CircleCloseFilled /></el-icon>
|
|
||||||
{{ stateMap[status.state](status.type) }}
|
|
||||||
</el-text>
|
|
||||||
<el-text v-else-if="status.state === State.STARTED">
|
|
||||||
<el-icon class="is-loading primary"><Loading /></el-icon>
|
|
||||||
{{ stateMap[status.state](status.type) }}
|
|
||||||
</el-text>
|
|
||||||
<el-text v-else-if="status.state === State.PENDING">
|
|
||||||
<el-icon class="is-loading primary"><Loading /></el-icon>
|
|
||||||
{{ stateMap[status.state](status.type) }}
|
|
||||||
</el-text>
|
|
||||||
<el-text v-else-if="aggStatus?.value === State.REVOKE">
|
|
||||||
<el-icon class="is-loading primary"><Loading /></el-icon>
|
|
||||||
{{ stateMap[aggStatus.value](aggStatus.key) }}
|
|
||||||
</el-text>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="5">
|
|
||||||
完成
|
|
||||||
{{
|
|
||||||
Object.keys(status.aggs ? status.aggs : {})
|
|
||||||
.filter((k) => k == State.SUCCESS)
|
|
||||||
.map((k) => status.aggs[k])
|
|
||||||
.reduce((x: any, y: any) => x + y, 0)
|
|
||||||
}}/{{
|
|
||||||
Object.values(status.aggs ? status.aggs : {}).reduce((x: any, y: any) => x + y, 0)
|
|
||||||
}}
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="9">
|
|
||||||
{{
|
|
||||||
status.time
|
|
||||||
? status.time[
|
|
||||||
status.state == State.REVOKED ? State.REVOKED : State.PENDING
|
|
||||||
]?.substring(0, 19)
|
|
||||||
: undefined
|
|
||||||
}}
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-text v-if="aggStatus?.value === State.SUCCESS || aggStatus?.value === State.REVOKED">
|
<el-text v-if="aggStatus?.value === State.SUCCESS || aggStatus?.value === State.REVOKED">
|
||||||
@ -72,11 +34,11 @@
|
|||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { Status, TaskType, State, type TaskTypeInterface } from '@/utils/status'
|
import { TaskType, State } from '@/utils/status'
|
||||||
import { mergeWith } from 'lodash'
|
import StatusTable from '@/views/document/component/StatusTable.vue'
|
||||||
const props = defineProps<{ status: string; statusMeta: any }>()
|
const props = defineProps<{ status: string; statusMeta: any }>()
|
||||||
|
const visible = ref<boolean>(false)
|
||||||
const checkList: Array<string> = [
|
const checkList: Array<string> = [
|
||||||
State.REVOKE,
|
State.REVOKE,
|
||||||
State.STARTED,
|
State.STARTED,
|
||||||
@ -112,56 +74,5 @@ const stateMap: any = {
|
|||||||
[State.FAILURE]: (type: number) => '失败',
|
[State.FAILURE]: (type: number) => '失败',
|
||||||
[State.SUCCESS]: (type: number) => '成功'
|
[State.SUCCESS]: (type: number) => '成功'
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseAgg = (agg: { count: number; status: string }) => {
|
|
||||||
const status = new Status(agg.status)
|
|
||||||
return Object.keys(TaskType)
|
|
||||||
.map((key) => {
|
|
||||||
const value = TaskType[key as keyof TaskTypeInterface]
|
|
||||||
return { [value]: { [status.task_status[value]]: agg.count } }
|
|
||||||
})
|
|
||||||
.reduce((x, y) => ({ ...x, ...y }), {})
|
|
||||||
}
|
|
||||||
|
|
||||||
const customizer: (x: any, y: any) => any = (objValue: any, srcValue: any) => {
|
|
||||||
if (objValue == undefined && srcValue) {
|
|
||||||
return srcValue
|
|
||||||
}
|
|
||||||
if (srcValue == undefined && objValue) {
|
|
||||||
return objValue
|
|
||||||
}
|
|
||||||
// 如果是数组,我们将元素进行聚合
|
|
||||||
if (typeof objValue === 'object' && typeof srcValue === 'object') {
|
|
||||||
// 若是object类型的对象,我们进行递归
|
|
||||||
return mergeWith(objValue, srcValue, customizer)
|
|
||||||
} else {
|
|
||||||
// 否则,单纯的将值进行累加
|
|
||||||
return objValue + srcValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const aggs = computed(() => {
|
|
||||||
return (props.statusMeta.aggs ? props.statusMeta.aggs : [])
|
|
||||||
.map((agg: any) => {
|
|
||||||
return parseAgg(agg)
|
|
||||||
})
|
|
||||||
.reduce((x: any, y: any) => {
|
|
||||||
return mergeWith(x, y, customizer)
|
|
||||||
}, {})
|
|
||||||
})
|
|
||||||
|
|
||||||
const statusTable = computed(() => {
|
|
||||||
return Object.keys(TaskType)
|
|
||||||
.map((key) => {
|
|
||||||
const value = TaskType[key as keyof TaskTypeInterface]
|
|
||||||
const parseStatus = new Status(props.status)
|
|
||||||
return {
|
|
||||||
type: value,
|
|
||||||
state: parseStatus.task_status[value],
|
|
||||||
aggs: aggs.value[value],
|
|
||||||
time: props.statusMeta.state_time[value]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter((item) => item.state !== State.IGNORED)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
110
ui/src/views/document/component/StatusTable.vue
Normal file
110
ui/src/views/document/component/StatusTable.vue
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<el-row :gutter="3" v-for="status in statusTable" :key="status.type">
|
||||||
|
<el-col :span="4">{{ taskTypeMap[status.type] }} </el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-text v-if="status.state === State.SUCCESS || status.state === State.REVOKED">
|
||||||
|
<el-icon class="success"><SuccessFilled /></el-icon>
|
||||||
|
{{ stateMap[status.state](status.type) }}
|
||||||
|
</el-text>
|
||||||
|
<el-text v-else-if="status.state === State.FAILURE">
|
||||||
|
<el-icon class="danger"><CircleCloseFilled /></el-icon>
|
||||||
|
{{ stateMap[status.state](status.type) }}
|
||||||
|
</el-text>
|
||||||
|
<el-text v-else-if="status.state === State.STARTED">
|
||||||
|
<el-icon class="is-loading primary"><Loading /></el-icon>
|
||||||
|
{{ stateMap[status.state](status.type) }}
|
||||||
|
</el-text>
|
||||||
|
<el-text v-else-if="status.state === State.PENDING">
|
||||||
|
<el-icon class="is-loading primary"><Loading /></el-icon>
|
||||||
|
{{ stateMap[status.state](status.type) }}
|
||||||
|
</el-text>
|
||||||
|
<el-text v-else-if="status.state === State.REVOKE">
|
||||||
|
<el-icon class="is-loading primary"><Loading /></el-icon>
|
||||||
|
{{ stateMap[status.state](status.type) }}
|
||||||
|
</el-text>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="7">
|
||||||
|
<span
|
||||||
|
:style="{ color: [State.FAILURE, State.REVOKED].includes(status.state) ? '#F54A45' : '' }"
|
||||||
|
>
|
||||||
|
完成
|
||||||
|
{{
|
||||||
|
Object.keys(status.aggs ? status.aggs : {})
|
||||||
|
.filter((k) => k == State.SUCCESS)
|
||||||
|
.map((k) => status.aggs[k])
|
||||||
|
.reduce((x: any, y: any) => x + y, 0)
|
||||||
|
}}/{{
|
||||||
|
Object.values(status.aggs ? status.aggs : {}).reduce((x: any, y: any) => x + y, 0)
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="9">
|
||||||
|
{{
|
||||||
|
status.time
|
||||||
|
? status.time[status.state == State.REVOKED ? State.REVOKED : State.PENDING]?.substring(
|
||||||
|
0,
|
||||||
|
19
|
||||||
|
)
|
||||||
|
: undefined
|
||||||
|
}}
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { Status, TaskType, State, type TaskTypeInterface } from '@/utils/status'
|
||||||
|
import { mergeWith } from 'lodash'
|
||||||
|
const props = defineProps<{ status: string; statusMeta: any; stateMap: any; taskTypeMap: any }>()
|
||||||
|
|
||||||
|
const parseAgg = (agg: { count: number; status: string }) => {
|
||||||
|
const status = new Status(agg.status)
|
||||||
|
return Object.keys(TaskType)
|
||||||
|
.map((key) => {
|
||||||
|
const value = TaskType[key as keyof TaskTypeInterface]
|
||||||
|
return { [value]: { [status.task_status[value]]: agg.count } }
|
||||||
|
})
|
||||||
|
.reduce((x, y) => ({ ...x, ...y }), {})
|
||||||
|
}
|
||||||
|
|
||||||
|
const customizer: (x: any, y: any) => any = (objValue: any, srcValue: any) => {
|
||||||
|
if (objValue == undefined && srcValue) {
|
||||||
|
return srcValue
|
||||||
|
}
|
||||||
|
if (srcValue == undefined && objValue) {
|
||||||
|
return objValue
|
||||||
|
}
|
||||||
|
// 如果是数组,我们将元素进行聚合
|
||||||
|
if (typeof objValue === 'object' && typeof srcValue === 'object') {
|
||||||
|
// 若是object类型的对象,我们进行递归
|
||||||
|
return mergeWith(objValue, srcValue, customizer)
|
||||||
|
} else {
|
||||||
|
// 否则,单纯的将值进行累加
|
||||||
|
return objValue + srcValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const aggs = computed(() => {
|
||||||
|
return (props.statusMeta.aggs ? props.statusMeta.aggs : [])
|
||||||
|
.map((agg: any) => {
|
||||||
|
return parseAgg(agg)
|
||||||
|
})
|
||||||
|
.reduce((x: any, y: any) => {
|
||||||
|
return mergeWith(x, y, customizer)
|
||||||
|
}, {})
|
||||||
|
})
|
||||||
|
|
||||||
|
const statusTable = computed(() => {
|
||||||
|
return Object.keys(TaskType)
|
||||||
|
.map((key) => {
|
||||||
|
const value = TaskType[key as keyof TaskTypeInterface]
|
||||||
|
const parseStatus = new Status(props.status)
|
||||||
|
return {
|
||||||
|
type: value,
|
||||||
|
state: parseStatus.task_status[value],
|
||||||
|
aggs: aggs.value[value],
|
||||||
|
time: props.statusMeta.state_time[value]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter((item) => item.state !== State.IGNORED)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss"></style>
|
||||||
@ -235,7 +235,25 @@
|
|||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div v-if="datasetDetail.type === '0'">
|
<div v-if="datasetDetail.type === '0'">
|
||||||
<span class="mr-4">
|
<span class="mr-4">
|
||||||
<el-tooltip effect="dark" content="向量化" placement="top">
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
v-if="
|
||||||
|
([State.STARTED, State.PENDING] as Array<string>).includes(
|
||||||
|
getTaskState(row.status, TaskType.EMBEDDING)
|
||||||
|
)
|
||||||
|
"
|
||||||
|
content="取消向量化"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
text
|
||||||
|
@click.stop="cancelTask(row, TaskType.EMBEDDING)"
|
||||||
|
>
|
||||||
|
<AppIcon iconName="app-close" style="font-size: 16px"></AppIcon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip v-else effect="dark" content="向量化" placement="top">
|
||||||
<el-button type="primary" text @click.stop="refreshDocument(row)">
|
<el-button type="primary" text @click.stop="refreshDocument(row)">
|
||||||
<AppIcon iconName="app-document-refresh" style="font-size: 16px"></AppIcon>
|
<AppIcon iconName="app-document-refresh" style="font-size: 16px"></AppIcon>
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -255,9 +273,20 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item @click="openGenerateDialog(row)">
|
<el-dropdown-item
|
||||||
|
v-if="
|
||||||
|
([State.STARTED, State.PENDING] as Array<string>).includes(
|
||||||
|
getTaskState(row.status, TaskType.GENERATE_PROBLEM)
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
||||||
|
>
|
||||||
<el-icon><Connection /></el-icon>
|
<el-icon><Connection /></el-icon>
|
||||||
生成关联问题
|
取消生成问题
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-else @click="openGenerateDialog(row)">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
生成问题
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item @click="openDatasetDialog(row)">
|
<el-dropdown-item @click="openDatasetDialog(row)">
|
||||||
<AppIcon iconName="app-migrate"></AppIcon>
|
<AppIcon iconName="app-migrate"></AppIcon>
|
||||||
@ -286,7 +315,11 @@
|
|||||||
<span class="mr-4">
|
<span class="mr-4">
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
effect="dark"
|
effect="dark"
|
||||||
v-if="getTaskState(row.status, TaskType.EMBEDDING) == State.STARTED"
|
v-if="
|
||||||
|
([State.STARTED, State.PENDING] as Array<string>).includes(
|
||||||
|
getTaskState(row.status, TaskType.EMBEDDING)
|
||||||
|
)
|
||||||
|
"
|
||||||
content="取消向量化"
|
content="取消向量化"
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
@ -318,7 +351,9 @@
|
|||||||
>
|
>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
v-if="
|
v-if="
|
||||||
getTaskState(row.status, TaskType.GENERATE_PROBLEM) == State.STARTED
|
([State.STARTED, State.PENDING] as Array<string>).includes(
|
||||||
|
getTaskState(row.status, TaskType.GENERATE_PROBLEM)
|
||||||
|
)
|
||||||
"
|
"
|
||||||
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -203,7 +203,7 @@ export const documentExtractNode = {
|
|||||||
config: {
|
config: {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
label: '文件内容',
|
label: '文档内容',
|
||||||
value: 'content'
|
value: 'content'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -131,7 +131,7 @@
|
|||||||
<template #label>
|
<template #label>
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
<div>历史聊天记录</div>
|
<div>历史聊天记录</div>
|
||||||
<el-select v-model="form_data.dialogue_type" type="small" style="width: 100px;">
|
<el-select v-model="form_data.dialogue_type" type="small" style="width: 100px">
|
||||||
<el-option label="节点" value="NODE" />
|
<el-option label="节点" value="NODE" />
|
||||||
<el-option label="工作流" value="WORKFLOW" />
|
<el-option label="工作流" value="WORKFLOW" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -143,9 +143,13 @@
|
|||||||
:value-on-clear="0"
|
:value-on-clear="0"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
|
:step="1"
|
||||||
|
:step-strictly="true"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="选择图片" :rules="{
|
<el-form-item
|
||||||
|
label="选择图片"
|
||||||
|
:rules="{
|
||||||
type: 'array',
|
type: 'array',
|
||||||
required: true,
|
required: true,
|
||||||
message: '请选择图片',
|
message: '请选择图片',
|
||||||
@ -232,7 +236,7 @@ const form = {
|
|||||||
is_result: true,
|
is_result: true,
|
||||||
temperature: null,
|
temperature: null,
|
||||||
max_tokens: null,
|
max_tokens: null,
|
||||||
image_list: ["start-node", "image"]
|
image_list: ['start-node', 'image']
|
||||||
}
|
}
|
||||||
|
|
||||||
const form_data = computed({
|
const form_data = computed({
|
||||||
@ -249,7 +253,6 @@ const form_data = computed({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
function getModel() {
|
function getModel() {
|
||||||
if (id) {
|
if (id) {
|
||||||
applicationApi.getApplicationImageModel(id).then((res: any) => {
|
applicationApi.getApplicationImageModel(id).then((res: any) => {
|
||||||
@ -268,9 +271,7 @@ function getProvider() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const model_change = (model_id?: string) => {
|
const model_change = (model_id?: string) => {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function submitSystemDialog(val: string) {
|
function submitSystemDialog(val: string) {
|
||||||
set(props.nodeModel.properties.node_data, 'system', val)
|
set(props.nodeModel.properties.node_data, 'system', val)
|
||||||
@ -286,10 +287,6 @@ onMounted(() => {
|
|||||||
|
|
||||||
set(props.nodeModel, 'validate', validate)
|
set(props.nodeModel, 'validate', validate)
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
<style scoped lang="scss">
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user