Skip to content

Commit

Permalink
Hotfix/0.4.1.1 (#1071)
Browse files Browse the repository at this point in the history
  • Loading branch information
zgqgit authored Jan 7, 2025
2 parents 5e3f25e + 64e5365 commit 62f995e
Show file tree
Hide file tree
Showing 15 changed files with 299 additions and 168 deletions.
5 changes: 5 additions & 0 deletions src/backend/bisheng/api/errcode/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,8 @@ class WorkflowNameExistsError(BaseErrorCode):
class FlowTemplateNameError(BaseErrorCode):
Code: int = 10530
Msg: str = '模板名称已存在'


class WorkFlowNodeUpdateError(BaseErrorCode):
Code: int = 10531
Msg: str = '<节点名称>功能已升级,需删除后重新拖入。'
7 changes: 5 additions & 2 deletions src/backend/bisheng/chat/clients/workflow_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from fastapi import Request, WebSocket, status
from loguru import logger

from bisheng.api.errcode.flow import WorkFlowWaitUserTimeoutError, WorkFlowNodeRunMaxTimesError
from bisheng.api.errcode.flow import WorkFlowWaitUserTimeoutError, WorkFlowNodeRunMaxTimesError, WorkFlowNodeUpdateError
from bisheng.api.services.audit_log import AuditLogService
from bisheng.api.services.user_service import UserPayload
from bisheng.api.utils import get_request_ip
Expand Down Expand Up @@ -180,11 +180,14 @@ async def workflow_run(self):
send_msg = False

if status_info['status'] == WorkflowStatus.FAILED.value:
if status_info['reason'].find('has run more than the maximum number of times') != -1:
if status_info['reason'].find('-- has run more than the maximum number of times') != -1:
await self.send_response('error', 'over', {'code': WorkFlowNodeRunMaxTimesError.Code,
'message': status_info['reason'].split('--')[0]})
elif status_info['reason'].find('workflow wait user input timeout') != -1:
await self.send_response('error', 'over', {'code': WorkFlowWaitUserTimeoutError.Code, 'message': ''})
elif status_info['reason'].find('-- node params is error') != -1:
await self.send_response('error', 'over',
{'code': WorkFlowNodeUpdateError.Code, 'message': status_info['reason'].split('--')[0]})
else:
await self.send_response('error', 'over', {'code': 500, 'message': status_info['reason']})
await self.send_response('processing', 'close', '')
Expand Down
188 changes: 94 additions & 94 deletions src/backend/bisheng/database/data/template.json

Large diffs are not rendered by default.

28 changes: 24 additions & 4 deletions src/backend/bisheng/workflow/nodes/rag/rag.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import json
import time
from typing import List, Any


from langchain_core.prompts import (ChatPromptTemplate, HumanMessagePromptTemplate,
SystemMessagePromptTemplate)

from bisheng.api.services.llm import LLMService
from bisheng.chat.clients.llm_callback import LLMRagNodeCallbackHandler
from bisheng.chat.types import IgnoreException
from bisheng.database.models.user import UserDao
from bisheng.interface.importing.utils import import_vectorstore
from bisheng.interface.initialize.loading import instantiate_vectorstore
from bisheng.utils.minio_client import MinioClient
from bisheng.workflow.callback.event import OutputMsgData, StreamMsgOverData
from bisheng.workflow.nodes.base import BaseNode
from bisheng.workflow.nodes.prompt_template import PromptTemplateParser
from bisheng_langchain.rag.bisheng_rag_chain import BishengRetrievalQA
from langchain_core.prompts import (ChatPromptTemplate, HumanMessagePromptTemplate,
SystemMessagePromptTemplate)


class RagNode(BaseNode):
Expand All @@ -20,11 +25,15 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# 判断是知识库还是临时文件列表
if 'knowledge' not in self.node_params:
raise IgnoreException(f'{self.name} -- node params is error')
self._knowledge_type = self.node_params['knowledge']['type']
self._knowledge_value = [
one['key'] for one in self.node_params['knowledge']['value']
]

self._minio_client = MinioClient()

self._knowledge_auth = self.node_params['user_auth']
self._max_chunk_size = int(self.node_params['max_chunk_size'])
self._sort_chunks = False
Expand Down Expand Up @@ -110,9 +119,19 @@ def parse_log(self, unique_id: str, result: dict) -> Any:
for key, val in result.items():
output_keys.append({'key': f'{self.id}.{key}', 'value': val, 'type': 'variable'})
source_documents.append([one.page_content for one in self._log_source_documents[key]])

tmp_retrieved_result = json.dumps(source_documents, indent=2, ensure_ascii=False)
tmp_retrieved_type = 'params'
if len(tmp_retrieved_result.encode('utf-8')) >= 50 * 1024: # 大于50kb的日志数据存文件
tmp_retrieved_type = 'file'
tmp_object_name = f'/workflow/source_document/{time.time()}.txt'
self._minio_client.upload_tmp(tmp_object_name, tmp_retrieved_result.encode('utf-8'))
share_url = self._minio_client.get_share_link(tmp_object_name, self._minio_client.tmp_bucket)
tmp_retrieved_result = self._minio_client.clear_minio_share_host(share_url)

ret = [
{'key': 'user_question', 'value': self.init_user_question(), "type": "params"},
{'key': 'retrieved_result', 'value': source_documents, "type": "params"},
{'key': 'retrieved_result', 'value': tmp_retrieved_result, "type": tmp_retrieved_type},
{'key': 'system_prompt', 'value': self._log_system_prompt, "type": "params"},
{'key': 'user_prompt', 'value': self._log_user_prompt, "type": "params"},
]
Expand All @@ -137,9 +156,10 @@ def init_qa_prompt(self):
if variable_map.get(f'{self.id}.retrieved_result') is None:
raise IgnoreException('用户提示词必须包含 retrieved_result 变量')
user_prompt = self._user_prompt.format(variable_map)
log_user_prompt = user_prompt.replace('$$question$$', '{user_question}').replace('$$context$$', '{retrieved_result}')
user_prompt = (user_prompt.replace('{', '{{').replace('}', '}}')
.replace('$$question$$', '{question}').replace('$$context$$', '{context}'))
self._log_user_prompt.append(user_prompt)
self._log_user_prompt.append(log_user_prompt)

variable_map = {}
for one in self._system_variables:
Expand Down
3 changes: 2 additions & 1 deletion src/bisheng-langchain/bisheng_langchain/gpts/load_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ def _get_dalle_image_generator(**kwargs: Any) -> Tool:
return DallEImageGenerator(
api_wrapper=AzureDallEWrapper(**kwargs)
)

kwargs['api_key'] = kwargs.pop('openai_api_key')
kwargs['base_url'] = kwargs.pop('openai_api_base', None)
return DallEImageGenerator(
api_wrapper=DallEAPIWrapper(
model='dall-e-3',
Expand Down
44 changes: 43 additions & 1 deletion src/frontend/public/locales/en/bs.json
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,46 @@
"jsonSample": "JSON Sample.json",
"selectQaKnowledgeLib": "Select QA Knowledge Library"
},
"label": {
"createTask": "Create Labeling Task",
"selectAppsToLabel": "Select Apps to Label",
"unmarkedConversationCount": "Current Unmarked Conversation Count",
"selectLabelers": "Select Labelers",
"cancel": "Cancel",
"create": "Create",
"confirmDelete": "Are you sure you want to delete this task?",
"delete": "Delete",
"taskId": "Task ID",
"taskStatus": "Task Status",
"creationTime": "Creation Time",
"createdBy": "Created By",
"labelingProgress": "Labeling Progress",
"actions": "Actions",
"view": "View",
"noData": "No Data",
"all": "All",
"notStarted": "Not Started",
"completed": "Completed",
"inProgress": "In Progress",
"taskStatusFilter": "Task Status Filter",
"maxAppsError": "You can select up to 30 apps",
"createSuccess": "Creation Successful",
"back": "Back",
"appName": "App Name",
"sessionCreationTime": "Session Creation Time",
"userFeedback": "User Feedback",
"annotationStatus": "Annotation Status",
"unannotated": "Unannotated",
"annotated": "Annotated",
"noAnnotationRequired": "No Annotation Required",
"annotator": "Annotator",
"returnToList": "Return to List",
"unlabeled": "Unlabeled",
"labeled": "Labeled",
"unnecessary": "Unnecessary",
"previousChat": "Previous Chat",
"nextChat": "Next Chat"
},
"errors": {
"10400": "Assistant does not exist",
"10401": "Failed to bring assistant online",
Expand Down Expand Up @@ -868,7 +908,8 @@
"10920": "QA Knowledge Base similarity question model not configured",
"10930": "This issue has been annotated",
"10527": "Workflow waits for user input timeout",
"10528": "{{type}}node execution exceeds maximum number of times"
"10528": "{{type}}node execution exceeds maximum number of times",
"10531": "{{type}} has been upgraded. You need to delete it and drag it in again."
},
"all": "All",
"confirmButton": "Confirm",
Expand Down Expand Up @@ -903,5 +944,6 @@
"required": "cannot be empty",
"addSimilarQuestion": "Add Similar Question",
"addQa": "Add QA",
"inserVar": "Insert variable",
"chatTips": "1. Please comply with the Cybersecurity Law of the People's Republic of China, the Data Security Law of the People's Republic of China, the Personal Information Protection Law of the People's Republic of China, and the Basic Requirements for the Security of Generative Artificial Intelligence Services;\n2. It is forbidden to upload confidential data that falls within the scope of the company's confidentiality management regulations;\n3. It is forbidden to upload data containing personal privacy information;\n4. It is forbidden to upload files containing malicious programs or viruses;\n5. It is forbidden to use AI to generate offensive code;\n6. It is forbidden to ask AI questions involving but not limited to explosives, terrorism, pornography, and information that endangers national and public security;\n7. AI-generated content is subject to the company's confidentiality management regulations. Users should judge the reasonableness of the generated content based on the actual situation to avoid risks caused by AI hallucinations."
}
44 changes: 43 additions & 1 deletion src/frontend/public/locales/zh/bs.json
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,46 @@
"jsonSample": "json格式示例.json",
"selectQaKnowledgeLib": "选择QA知识库"
},
"label": {
"createTask": "创建标注任务",
"selectAppsToLabel": "选择要标注的应用",
"unmarkedConversationCount": "当前未标注会话数",
"selectLabelers": "选择标注人",
"cancel": "取消",
"create": "创建",
"confirmDelete": "您确定要删除此任务吗?",
"delete": "删除",
"taskId": "任务 ID",
"taskStatus": "任务状态",
"creationTime": "创建时间",
"createdBy": "创建人",
"labelingProgress": "标注进度",
"actions": "操作",
"view": "查看",
"noData": "暂无数据",
"all": "全部",
"notStarted": "未开始",
"completed": "已完成",
"inProgress": "进行中",
"taskStatusFilter": "任务状态筛选",
"maxAppsError": "最多选择30个应用",
"createSuccess": "创建成功",
"back": "返回",
"appName": "应用名称",
"sessionCreationTime": "会话创建时间",
"userFeedback": "用户反馈",
"annotationStatus": "标注状态",
"unannotated": "未标注",
"annotated": "已标注",
"noAnnotationRequired": "无需标注",
"annotator": "标注人",
"returnToList": "返回列表",
"unlabeled": "未标注",
"labeled": "已标注",
"unnecessary": "无需标注",
"previousChat": "上一条会话",
"nextChat": "下一条会话"
},
"errors": {
"10400": "助手不存在",
"10401": "助手上线失败",
Expand Down Expand Up @@ -865,7 +905,8 @@
"10920": "未配置QA知识库相似问模型",
"10930": "该问题已被标注过",
"10527": "工作流等待用户输入超时",
"10528": "{{type}}节点执行超过最大次数"
"10528": "{{type}}节点执行超过最大次数",
"10531": "{{type}}功能已升级,需删除后重新拖入"
},
"all": "全部",
"confirmButton": "确定",
Expand Down Expand Up @@ -903,5 +944,6 @@
"success": "成功",
"addSimilarQuestion": "添加相似问题",
"addQa": "添加QA",
"inserVar": "插入变量",
"chatTips": "1. 请遵守《中华人民共和国网络安全法》《中华人民共和国数据安全法》《中华人民共和国个人信息保护法》及《生成式人工智能服务安全基本要求》;\n2. 禁止上传涉及公司保密管理规定范围内的保密数据;\n3. 禁止上传包含个人隐私信息的数据;\n4. 禁止上传包含恶意程序或病毒的文件;\n5. 禁止使用 AI 生成攻击性代码;\n6. 禁止向 AI 提问包括但不限于涉爆涉恐涉黄及危害国家安全及公共安全的违法不良信息;\n7. AI 生成内容受到公司保密管理规定约束。用户应根据实际情况判断生成内容的合理性,避免 AI 幻觉造成的风险。"
}
2 changes: 1 addition & 1 deletion src/frontend/src/components/bs-icons/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { forwardRef } from "react";
import Helper from "./helper.svg?react";
import Flow from "./flow.svg?react";
import Abilities from "./Abilities.svg?react";
import Abilities from "./abilities.svg?react";

export const HelperIcon = forwardRef<
SVGSVGElement & { className: any },
Expand Down
30 changes: 26 additions & 4 deletions src/frontend/src/pages/BuildPage/flow/FlowNode/RunLog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import NodeLogo from "./NodeLogo";
import { ResultText } from "./RunTest";
import { Button } from "@/components/bs-ui/button";
import { downloadFile } from "@/util/utils";
import useFlowStore from "../flowStore";

const enum Status {
normal = 'normal',
Expand Down Expand Up @@ -55,7 +58,9 @@ const Log = ({ type, name, data }) => {
<X size={18} className="cursor-pointer" onClick={() => setOpen(false)} />
</div>
<div className="">
{Object.keys(data).map(key => <ResultText title={key} value={data[key]} key={key} />)}
{Object.keys(data).map(key => data[key].type === 'file' ?
<ResultFile title={key} name={name} fileUrl={data[key].value} key={key} />
: <ResultText title={key} value={data[key]} key={key} />)}
</div>
</div>
)}
Expand All @@ -68,7 +73,6 @@ export default function RunLog({ node, children }) {
const [state, setState] = useState<Status>(Status.normal)
const [data, setData] = useState<any>({})
const { t } = useTranslation('flow')

// 订阅日志事件
useEffect(() => {
const onNodeLogEvent = (e) => {
Expand All @@ -80,9 +84,9 @@ export default function RunLog({ node, children }) {
const newData = data.reduce((res, item) => {
if (item.type === 'variable') {
const key = item.key.split('.')
res[key[key.length - 1]] = item.value
res[key[key.length - 1]] = { type: item.type, value: item.value }
} else {
res[item.key] = item.value
res[item.key] = { type: item.type, value: item.value }
}
return res
}, {})
Expand Down Expand Up @@ -162,3 +166,21 @@ export default function RunLog({ node, children }) {
</div>
);
};


// 下载文件
export const ResultFile = ({ title, name, fileUrl }: { title: string, name: string, fileUrl: string }) => {
const { flow } = useFlowStore();

const handleDownload = (e) => {
downloadFile(fileUrl, `${flow.name}_${name}_检索结果`)
}

return <div className="mb-2 rounded-md border bg-search-input text-sm shadow-sm">
<div className="border-b px-2 flex justify-between items-center">
<p>{title}</p>
</div>
<textarea defaultValue={'检索结果过长,请下载后查看'} disabled className="w-full h-12 p-2 block text-muted-foreground dark:bg-black " />
<Button onClick={handleDownload} className="h-6 mt-2">下载完整内容</Button>
</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function ReportWordEdit({ versionKey, nodeId, onChange }) {
<Button variant="outline" size="icon" className="bg-[#fff] size-8"><ChevronLeft /></Button>
</DialogClose>
<SelectVar nodeId={nodeId} itemKey={''} onSelect={(E, v) => handleInset(`${E.id}.${v.value}`)}>
<Button className="h-8">插入变量 <ChevronDown size={14} /></Button>
<Button className="h-8">{t('inserVar')}<ChevronDown size={14} /></Button>
</SelectVar>
</div>
<Word data={docx} workflow></Word>
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/pages/BuildPage/flow/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ const useNodeEvent = (flow) => {
};
const findOutType = (nodeId) => {
if (!nodeId.startsWith('output')) return '';
return flow.nodes.find(node => node.id === nodeId).data.group_params[0].params[1].value.type;
return flow.nodes.find(node => node.id === nodeId)?.data.group_params[0].params[1].value.type || '';
};

const traverseTree = (nodeId, branchId, nodeIds) => {
Expand Down
Loading

0 comments on commit 62f995e

Please sign in to comment.