parent
92105e9a0b
commit
ab0fc517dc
@ -35,3 +35,4 @@ curl --location --request POST 'https://{{host}}/api/admin/initv4820' \
|
|||||||
3. 新增 - markdown 语法扩展,支持音视频(代码块 audio 和 video)。
|
3. 新增 - markdown 语法扩展,支持音视频(代码块 audio 和 video)。
|
||||||
4. 优化 - 页面组件抽离,减少页面组件路由。
|
4. 优化 - 页面组件抽离,减少页面组件路由。
|
||||||
5. 优化 - 全文检索,忽略大小写。
|
5. 优化 - 全文检索,忽略大小写。
|
||||||
|
6. 优化 - 问答生成和增强索引改成流输出,避免部分模型超时。
|
||||||
@ -2,7 +2,8 @@ import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
|||||||
import {
|
import {
|
||||||
ChatCompletionCreateParamsNonStreaming,
|
ChatCompletionCreateParamsNonStreaming,
|
||||||
ChatCompletionCreateParamsStreaming,
|
ChatCompletionCreateParamsStreaming,
|
||||||
ChatCompletionMessageParam
|
ChatCompletionMessageParam,
|
||||||
|
StreamChatType
|
||||||
} from '@fastgpt/global/core/ai/type';
|
} from '@fastgpt/global/core/ai/type';
|
||||||
import { countGptMessagesTokens } from '../../common/string/tiktoken';
|
import { countGptMessagesTokens } from '../../common/string/tiktoken';
|
||||||
import { getLLMModel } from './model';
|
import { getLLMModel } from './model';
|
||||||
@ -87,3 +88,12 @@ export const llmCompletionsBodyFormat = <T extends CompletionsBodyType>(
|
|||||||
|
|
||||||
return requestBody as InferCompletionsBody<T>;
|
return requestBody as InferCompletionsBody<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const llmStreamResponseToText = async (response: StreamChatType) => {
|
||||||
|
let answer = '';
|
||||||
|
for await (const part of response) {
|
||||||
|
const content = part.choices?.[0]?.delta?.content || '';
|
||||||
|
answer += content;
|
||||||
|
}
|
||||||
|
return answer;
|
||||||
|
};
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export const useRequest2 = <TData, TParams extends any[]>(
|
|||||||
...rest,
|
...rest,
|
||||||
onError: (err, params) => {
|
onError: (err, params) => {
|
||||||
rest?.onError?.(err, params);
|
rest?.onError?.(err, params);
|
||||||
if (errorToast !== undefined) {
|
if (errorToast !== '') {
|
||||||
const errText = t(getErrText(err, errorToast || '') as any);
|
const errText = t(getErrText(err, errorToast || '') as any);
|
||||||
if (errText) {
|
if (errText) {
|
||||||
toast({
|
toast({
|
||||||
|
|||||||
@ -93,10 +93,10 @@
|
|||||||
"code_error.team_error.org_parent_not_exist": "Parent organization does not exist",
|
"code_error.team_error.org_parent_not_exist": "Parent organization does not exist",
|
||||||
"code_error.team_error.over_size": "error.team.overSize",
|
"code_error.team_error.over_size": "error.team.overSize",
|
||||||
"code_error.team_error.plugin_amount_not_enough": "Plugin Limit Reached",
|
"code_error.team_error.plugin_amount_not_enough": "Plugin Limit Reached",
|
||||||
"code_error.team_error.re_rank_not_enough": "Unauthorized to Use Re-Rank",
|
"code_error.team_error.re_rank_not_enough": "Search rearrangement cannot be used in the free version~",
|
||||||
"code_error.team_error.un_auth": "Unauthorized to Operate This Team",
|
"code_error.team_error.un_auth": "Unauthorized to Operate This Team",
|
||||||
"code_error.team_error.user_not_active": "The user did not accept or has left the team",
|
"code_error.team_error.user_not_active": "The user did not accept or has left the team",
|
||||||
"code_error.team_error.website_sync_not_enough": "Unauthorized to Use Website Sync",
|
"code_error.team_error.website_sync_not_enough": "The free version cannot be synchronized with the web site ~",
|
||||||
"code_error.token_error_code.403": "Invalid Login Status, Please Re-login",
|
"code_error.token_error_code.403": "Invalid Login Status, Please Re-login",
|
||||||
"code_error.user_error.balance_not_enough": "Insufficient Account Balance",
|
"code_error.user_error.balance_not_enough": "Insufficient Account Balance",
|
||||||
"code_error.user_error.bin_visitor_guest": "You Are Currently a Guest, Unauthorized to Operate",
|
"code_error.user_error.bin_visitor_guest": "You Are Currently a Guest, Unauthorized to Operate",
|
||||||
|
|||||||
@ -97,10 +97,10 @@
|
|||||||
"code_error.team_error.org_parent_not_exist": "父部门不存在",
|
"code_error.team_error.org_parent_not_exist": "父部门不存在",
|
||||||
"code_error.team_error.over_size": "error.team.overSize",
|
"code_error.team_error.over_size": "error.team.overSize",
|
||||||
"code_error.team_error.plugin_amount_not_enough": "插件数量已达上限~",
|
"code_error.team_error.plugin_amount_not_enough": "插件数量已达上限~",
|
||||||
"code_error.team_error.re_rank_not_enough": "无权使用检索重排~",
|
"code_error.team_error.re_rank_not_enough": "免费版无法使用检索重排~",
|
||||||
"code_error.team_error.un_auth": "无权操作该团队",
|
"code_error.team_error.un_auth": "无权操作该团队",
|
||||||
"code_error.team_error.user_not_active": "用户未接受或已离开团队",
|
"code_error.team_error.user_not_active": "用户未接受或已离开团队",
|
||||||
"code_error.team_error.website_sync_not_enough": "无权使用Web站点同步~",
|
"code_error.team_error.website_sync_not_enough": "免费版无法使用Web站点同步~",
|
||||||
"code_error.token_error_code.403": "登录状态无效,请重新登录",
|
"code_error.token_error_code.403": "登录状态无效,请重新登录",
|
||||||
"code_error.user_error.balance_not_enough": "账号余额不足~",
|
"code_error.user_error.balance_not_enough": "账号余额不足~",
|
||||||
"code_error.user_error.bin_visitor_guest": "您当前身份为游客,无权操作",
|
"code_error.user_error.bin_visitor_guest": "您当前身份为游客,无权操作",
|
||||||
|
|||||||
@ -92,10 +92,10 @@
|
|||||||
"code_error.team_error.org_parent_not_exist": "父組織不存在",
|
"code_error.team_error.org_parent_not_exist": "父組織不存在",
|
||||||
"code_error.team_error.over_size": "error.team.overSize",
|
"code_error.team_error.over_size": "error.team.overSize",
|
||||||
"code_error.team_error.plugin_amount_not_enough": "已達外掛程式數量上限",
|
"code_error.team_error.plugin_amount_not_enough": "已達外掛程式數量上限",
|
||||||
"code_error.team_error.re_rank_not_enough": "無權使用結果重新排名",
|
"code_error.team_error.re_rank_not_enough": "免費版無法使用檢索重排~",
|
||||||
"code_error.team_error.un_auth": "無權操作此團隊",
|
"code_error.team_error.un_auth": "無權操作此團隊",
|
||||||
"code_error.team_error.user_not_active": "使用者未接受或已離開團隊",
|
"code_error.team_error.user_not_active": "使用者未接受或已離開團隊",
|
||||||
"code_error.team_error.website_sync_not_enough": "無權使用網站同步",
|
"code_error.team_error.website_sync_not_enough": "免費版無法使用Web站點同步~",
|
||||||
"code_error.token_error_code.403": "登入狀態無效,請重新登入",
|
"code_error.token_error_code.403": "登入狀態無效,請重新登入",
|
||||||
"code_error.user_error.balance_not_enough": "帳戶餘額不足",
|
"code_error.user_error.balance_not_enough": "帳戶餘額不足",
|
||||||
"code_error.user_error.bin_visitor_guest": "您目前身份為訪客,無權操作",
|
"code_error.user_error.bin_visitor_guest": "您目前身份為訪客,無權操作",
|
||||||
|
|||||||
@ -1,21 +1,12 @@
|
|||||||
### FastGPT V4.8.16 更新说明
|
### FastGPT V4.8.20 更新说明
|
||||||
|
|
||||||
1. 新增 - SearXNG 搜索插件[点击查看教程](https://doc.fastgpt.cn//docs/guide/plugins/searxng_plugin_guide/)
|
|
||||||
2. 新增 - 商业版支持 API 知识库和链接集合定时同步。
|
|
||||||
3. 新增 - 猜你想问支持选择模型和自定义提示词。
|
|
||||||
4. 新增 - 钉钉和企微机器人 webhook 插件。
|
|
||||||
5. 新增 - 商业版支持钉钉 SSO 登录配置。[点击查看教程](https://doc.fastgpt.cn//docs/guide/admin/sso_dingtalk/)
|
|
||||||
6. 新增 - 商业版支持飞书和语雀知识库导入。[点击查看教程](https://doc.fastgpt.cn//docs/guide/knowledge_base/lark_dataset/)
|
|
||||||
7. 新增 - sandbox 新增 createHmac 加密全局方法。
|
|
||||||
8. 新增 - 工作流右键支持全部折叠。
|
|
||||||
9. 优化 - 工作流/简易模式变量初始化代码,去除监听初始化,避免因渲染顺序不一致导致的失败。
|
|
||||||
10. 优化 - 工作流获取数据类型不一致数据时,增加类型转化,避免 undefined。
|
|
||||||
11. 修复 - 无法自动切换默认语言。增加分享链接,强制执行一次切换默认语言。
|
|
||||||
12. 修复 - 数组选择器自动兼容 4.8.13 以前的数据。
|
|
||||||
13. 修复 - 站点同步知识库,链接同步时未使用选择器。
|
|
||||||
14. 修复 - 简易模式转工作流,没有把系统配置项转化。
|
|
||||||
15. 修复 - 插件独立运行,变量初始值未赋上。
|
|
||||||
16. 修复 - 工作流使用弹窗组件时,关闭弹窗后,有时候会出现页面偏移。
|
|
||||||
17. 修复 - 插件调试时,日志未保存插件输入参数。
|
|
||||||
|
|
||||||
|
1. 新增 - 使用记录导出和仪表盘。
|
||||||
|
2. 新增 - markdown 语法扩展,支持音视频(代码块 audio 和 video)。
|
||||||
|
3. 新增 - 飞书/语雀知识库。
|
||||||
|
4. 新增 - 工作流知识库检索支持按知识库权限进行过滤。
|
||||||
|
5. 新增 - 流程等待插件,可以等待 n 毫秒后继续执行流程。
|
||||||
|
6. 新增 - 飞书机器人接入,支持配置私有化飞书地址。
|
||||||
|
7. 新增 - 支持通过 JSON 配置直接创建应用。
|
||||||
|
8. 新增 - 支持通过 CURL 脚本快速创建 HTTP 插件。
|
||||||
|
9. 新增 - 支持部门架构权限模式。
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,10 @@ const NotSufficientModal = ({ type }: { type: NotSufficientModalType }) => {
|
|||||||
[TeamErrEnum.datasetSizeNotEnough]: t('common:support.wallet.Dataset_not_sufficient'),
|
[TeamErrEnum.datasetSizeNotEnough]: t('common:support.wallet.Dataset_not_sufficient'),
|
||||||
[TeamErrEnum.datasetAmountNotEnough]: t('common:support.wallet.Dataset_amount_not_sufficient'),
|
[TeamErrEnum.datasetAmountNotEnough]: t('common:support.wallet.Dataset_amount_not_sufficient'),
|
||||||
[TeamErrEnum.teamMemberOverSize]: t('common:support.wallet.Team_member_over_size'),
|
[TeamErrEnum.teamMemberOverSize]: t('common:support.wallet.Team_member_over_size'),
|
||||||
[TeamErrEnum.appAmountNotEnough]: t('common:support.wallet.App_amount_not_sufficient')
|
[TeamErrEnum.appAmountNotEnough]: t('common:support.wallet.App_amount_not_sufficient'),
|
||||||
|
[TeamErrEnum.pluginAmountNotEnough]: t('common:support.wallet.App_amount_not_sufficient'),
|
||||||
|
[TeamErrEnum.websiteSyncNotEnough]: t('common:code_error.team_error.website_sync_not_enough'),
|
||||||
|
[TeamErrEnum.reRankNotEnough]: t('common:code_error.team_error.re_rank_not_enough')
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -4,9 +4,9 @@ import { useTranslation } from 'next-i18next';
|
|||||||
import { Box, ModalBody } from '@chakra-ui/react';
|
import { Box, ModalBody } from '@chakra-ui/react';
|
||||||
import { checkBalancePayResult } from '@/web/support/wallet/bill/api';
|
import { checkBalancePayResult } from '@/web/support/wallet/bill/api';
|
||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
|
||||||
import LightTip from '@fastgpt/web/components/common/LightTip';
|
import LightTip from '@fastgpt/web/components/common/LightTip';
|
||||||
import QRCode from 'qrcode';
|
import QRCode from 'qrcode';
|
||||||
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
|
|
||||||
export type QRPayProps = {
|
export type QRPayProps = {
|
||||||
readPrice: number;
|
readPrice: number;
|
||||||
@ -54,35 +54,16 @@ const QRCodePayModal = ({
|
|||||||
drawCode();
|
drawCode();
|
||||||
}, [drawCode]);
|
}, [drawCode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useRequest2(() => checkBalancePayResult(billId), {
|
||||||
let timer: NodeJS.Timeout;
|
manual: false,
|
||||||
const check = async () => {
|
pollingInterval: 2000,
|
||||||
try {
|
onSuccess: (res) => {
|
||||||
const res = await checkBalancePayResult(billId);
|
if (res) {
|
||||||
if (res) {
|
onSuccess?.();
|
||||||
try {
|
}
|
||||||
await onSuccess?.();
|
},
|
||||||
toast({
|
errorToast: ''
|
||||||
title: res,
|
});
|
||||||
status: 'success'
|
|
||||||
});
|
|
||||||
return clearTimeout(timer);
|
|
||||||
} catch (error) {
|
|
||||||
toast({
|
|
||||||
title: getErrText(error),
|
|
||||||
status: 'error'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {}
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer = setTimeout(check, 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
check();
|
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
}, [billId, drawCode, onSuccess, toast]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen title={t('common:user.Pay')} iconSrc="/imgs/modal/pay.svg">
|
<MyModal isOpen title={t('common:user.Pay')} iconSrc="/imgs/modal/pay.svg">
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import {
|
|||||||
} from '@fastgpt/service/common/string/tiktoken/index';
|
} from '@fastgpt/service/common/string/tiktoken/index';
|
||||||
import { pushDataListToTrainingQueueByCollectionId } from '@fastgpt/service/core/dataset/training/controller';
|
import { pushDataListToTrainingQueueByCollectionId } from '@fastgpt/service/core/dataset/training/controller';
|
||||||
import { loadRequestMessages } from '@fastgpt/service/core/chat/utils';
|
import { loadRequestMessages } from '@fastgpt/service/core/chat/utils';
|
||||||
import { llmCompletionsBodyFormat } from '@fastgpt/service/core/ai/utils';
|
import { llmCompletionsBodyFormat, llmStreamResponseToText } from '@fastgpt/service/core/ai/utils';
|
||||||
|
|
||||||
const reduceQueue = () => {
|
const reduceQueue = () => {
|
||||||
global.qaQueueLen = global.qaQueueLen > 0 ? global.qaQueueLen - 1 : 0;
|
global.qaQueueLen = global.qaQueueLen > 0 ? global.qaQueueLen - 1 : 0;
|
||||||
@ -44,7 +44,7 @@ export async function generateQA(): Promise<any> {
|
|||||||
{
|
{
|
||||||
mode: TrainingModeEnum.qa,
|
mode: TrainingModeEnum.qa,
|
||||||
retryCount: { $gte: 0 },
|
retryCount: { $gte: 0 },
|
||||||
lockTime: { $lte: addMinutes(new Date(), -6) }
|
lockTime: { $lte: addMinutes(new Date(), -10) }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lockTime: new Date(),
|
lockTime: new Date(),
|
||||||
@ -120,12 +120,12 @@ ${replaceVariable(Prompt_AgentQA.fixedText, { text })}`;
|
|||||||
model: modelData.model,
|
model: modelData.model,
|
||||||
temperature: 0.3,
|
temperature: 0.3,
|
||||||
messages: await loadRequestMessages({ messages, useVision: false }),
|
messages: await loadRequestMessages({ messages, useVision: false }),
|
||||||
stream: false
|
stream: true
|
||||||
},
|
},
|
||||||
modelData
|
modelData
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
const answer = chatResponse.choices?.[0].message?.content || '';
|
const answer = await llmStreamResponseToText(chatResponse);
|
||||||
|
|
||||||
const qaArr = formatSplitText(answer, text); // 格式化后的QA对
|
const qaArr = formatSplitText(answer, text); // 格式化后的QA对
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export async function generateVector(): Promise<any> {
|
|||||||
{
|
{
|
||||||
mode: TrainingModeEnum.chunk,
|
mode: TrainingModeEnum.chunk,
|
||||||
retryCount: { $gte: 0 },
|
retryCount: { $gte: 0 },
|
||||||
lockTime: { $lte: addMinutes(new Date(), -6) }
|
lockTime: { $lte: addMinutes(new Date(), -3) }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
lockTime: new Date(),
|
lockTime: new Date(),
|
||||||
|
|||||||
@ -101,6 +101,7 @@ function checkRes(data: ResponseDataType) {
|
|||||||
*/
|
*/
|
||||||
function responseError(err: any) {
|
function responseError(err: any) {
|
||||||
console.log('error->', '请求错误', err);
|
console.log('error->', '请求错误', err);
|
||||||
|
const data = err?.response?.data || err;
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
return Promise.reject({ message: '未知错误' });
|
return Promise.reject({ message: '未知错误' });
|
||||||
@ -108,8 +109,12 @@ function responseError(err: any) {
|
|||||||
if (typeof err === 'string') {
|
if (typeof err === 'string') {
|
||||||
return Promise.reject({ message: err });
|
return Promise.reject({ message: err });
|
||||||
}
|
}
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
return Promise.reject(data);
|
||||||
|
}
|
||||||
|
|
||||||
// 有报错响应
|
// 有报错响应
|
||||||
if (err?.code in TOKEN_ERROR_CODE || err?.response?.data?.code in TOKEN_ERROR_CODE) {
|
if (data?.code in TOKEN_ERROR_CODE) {
|
||||||
if (!['/chat/share', '/chat/team', '/login'].includes(window.location.pathname)) {
|
if (!['/chat/share', '/chat/team', '/login'].includes(window.location.pathname)) {
|
||||||
clearToken();
|
clearToken();
|
||||||
window.location.replace(
|
window.location.replace(
|
||||||
@ -120,18 +125,18 @@ function responseError(err: any) {
|
|||||||
return Promise.reject({ message: i18nT('common:unauth_token') });
|
return Promise.reject({ message: i18nT('common:unauth_token') });
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
err?.statusText === TeamErrEnum.aiPointsNotEnough ||
|
data?.statusText === TeamErrEnum.aiPointsNotEnough ||
|
||||||
err?.statusText === TeamErrEnum.datasetSizeNotEnough ||
|
data?.statusText === TeamErrEnum.datasetSizeNotEnough ||
|
||||||
err?.statusText === TeamErrEnum.datasetAmountNotEnough ||
|
data?.statusText === TeamErrEnum.datasetAmountNotEnough ||
|
||||||
err?.statusText === TeamErrEnum.appAmountNotEnough
|
data?.statusText === TeamErrEnum.appAmountNotEnough ||
|
||||||
|
data?.statusText === TeamErrEnum.pluginAmountNotEnough ||
|
||||||
|
data?.statusText === TeamErrEnum.websiteSyncNotEnough ||
|
||||||
|
data?.statusText === TeamErrEnum.reRankNotEnough
|
||||||
) {
|
) {
|
||||||
useSystemStore.getState().setNotSufficientModalType(err.statusText);
|
useSystemStore.getState().setNotSufficientModalType(data.statusText);
|
||||||
return Promise.reject(err);
|
return Promise.reject(data);
|
||||||
}
|
}
|
||||||
if (err?.response?.data) {
|
return Promise.reject(data);
|
||||||
return Promise.reject(err?.response?.data);
|
|
||||||
}
|
|
||||||
return Promise.reject(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 创建请求实例 */
|
/* 创建请求实例 */
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export const useInitApp = () => {
|
|||||||
|
|
||||||
useRequest2(initFetch, {
|
useRequest2(initFetch, {
|
||||||
manual: false,
|
manual: false,
|
||||||
pollingInterval: 300000
|
pollingInterval: 300000 // 5 minutes refresh
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user