4.7-alpha2 (#1027)

* feat: stop toolCall and rename some field. (#46)

* perf: node delete tip;pay tip

* fix: toolCall cannot save child answer

* feat: stop tool

* fix: team modal

* fix feckbackMoal  auth bug (#47)

* 简单的支持提示词运行tool。优化workflow模板 (#49)

* remove templates

* fix: request body undefined

* feat: prompt tool run

* feat: workflow tamplates modal

* perf: plugin start

* 4.7 (#50)

* fix docker-compose download url (#994)

original code is a bad url with '404 NOT FOUND' return.
fix docker-compose download url, add 'v' before docker-compose version

* Update ai_settings.md (#1000)

* Update configuration.md

* Update configuration.md

* Fix history in classifyQuestion and extract modules (#1012)

* Fix history in classifyQuestion and extract modules

* Add chatValue2RuntimePrompt import and update text formatting

* flow controller to packages

* fix: rerank select

* modal ui

* perf: modal code path

* point not sufficient

* feat: http url support variable

* fix http key

* perf: prompt

* perf: ai setting modal

* simple edit ui

---------

Co-authored-by: entorick <entorick11@qq.com>
Co-authored-by: liujianglc <liujianglc@163.com>
Co-authored-by: Fengrui Liu <liufengrui.work@bytedance.com>

* fix team share redirect to login (#51)

* feat: support openapi import plugins (#48)

* feat: support openapi import plugins

* feat: import from url

* fix: add body params parse

* fix build

* fix

* fix

* fix

* tool box ui (#52)

* fix: training queue

* feat: simple edit tool select

* perf: simple edit dataset prompt

* fix: chatbox tool ux

* feat: quote prompt module

* perf: plugin tools sign

* perf: model avatar

* tool selector ui

* feat: max histories

* perf: http plugin import (#53)

* perf: plugin http import

* chatBox ui

* perf: name

* fix: Node template card (#54)

* fix: ts

* setting modal

* package

* package

* feat: add plugins search (#57)

* feat: add plugins search

* perf: change http plugin header input

* Yjl (#56)

* perf: prompt tool call

* perf: chat box ux

* doc

* doc

* price tip

* perf: tool selector

* ui'

* fix: vector queue

* fix: empty tool and empty response

* fix: empty msg

* perf: pg index

* perf: ui tip

* doc

* tool tip

---------

Co-authored-by: yst <77910600+yu-and-liu@users.noreply.github.com>
Co-authored-by: entorick <entorick11@qq.com>
Co-authored-by: liujianglc <liujianglc@163.com>
Co-authored-by: Fengrui Liu <liufengrui.work@bytedance.com>
Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
Archer
2024-03-21 13:32:31 +08:00
committed by GitHub
parent 6d4b331db9
commit 9d27de154b
322 changed files with 9282 additions and 6498 deletions

View File

@@ -10,6 +10,8 @@ import {
EventStreamContentType,
fetchEventSource
} from '@fortaine/fetch-event-source';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
import { useSystemStore } from '../system/useSystemStore';
type StreamFetchProps = {
url?: string;
@@ -34,13 +36,22 @@ export const streamFetch = ({
// response data
let responseText = '';
let remainTextList: { event: `${SseResponseEventEnum}`; text: string }[] = [];
let errMsg = '';
let responseQueue: (
| { event: SseResponseEventEnum.fastAnswer | SseResponseEventEnum.answer; text: string }
| {
event:
| SseResponseEventEnum.toolCall
| SseResponseEventEnum.toolParams
| SseResponseEventEnum.toolResponse;
[key: string]: any;
}
)[] = [];
let errMsg: string | undefined;
let responseData: ChatHistoryItemResType[] = [];
let finished = false;
const finish = () => {
if (errMsg) {
if (errMsg !== undefined) {
return failedFinish();
}
return resolve({
@@ -51,39 +62,41 @@ export const streamFetch = ({
const failedFinish = (err?: any) => {
finished = true;
reject({
message: getErrText(err, errMsg || '响应过程出现异常~'),
message: getErrText(err, errMsg ?? '响应过程出现异常~'),
responseText
});
};
const isAnswerEvent = (event: `${SseResponseEventEnum}`) =>
event === SseResponseEventEnum.answer || event === SseResponseEventEnum.fastAnswer;
// animate response to make it looks smooth
function animateResponseText() {
// abort message
if (abortCtrl.signal.aborted) {
remainTextList.forEach((item) => {
responseQueue.forEach((item) => {
onMessage(item);
if (item.event === SseResponseEventEnum.answer) {
if (isAnswerEvent(item.event)) {
responseText += item.text;
}
});
return finish();
}
if (remainTextList.length > 0) {
const fetchCount = Math.max(1, Math.round(remainTextList.length / 60));
if (responseQueue.length > 0) {
const fetchCount = Math.max(1, Math.round(responseQueue.length / 10));
for (let i = 0; i < fetchCount; i++) {
const item = remainTextList[i];
const item = responseQueue[i];
onMessage(item);
if (item.event === SseResponseEventEnum.answer) {
if (isAnswerEvent(item.event)) {
responseText += item.text;
}
}
remainTextList = remainTextList.slice(fetchCount);
responseQueue = responseQueue.slice(fetchCount);
}
if (finished && remainTextList.length === 0) {
if (finished && responseQueue.length === 0) {
return finish();
}
@@ -153,28 +166,23 @@ export const streamFetch = ({
return {};
}
})();
if (event === SseResponseEventEnum.answer) {
const text: string = parseJson?.choices?.[0]?.delta?.content || '';
for (const item of text) {
remainTextList.push({
event,
text: item
});
}
} else if (event === SseResponseEventEnum.fastAnswer) {
const text: string = parseJson?.choices?.[0]?.delta?.content || '';
remainTextList.push({
// console.log(parseJson, event);
if (event === SseResponseEventEnum.answer || event === SseResponseEventEnum.fastAnswer) {
const text = parseJson.choices?.[0]?.delta?.content || '';
responseQueue.push({
event,
text
});
} else if (
event === SseResponseEventEnum.flowNodeStatus ||
event === SseResponseEventEnum.toolCall ||
event === SseResponseEventEnum.toolParams ||
event === SseResponseEventEnum.toolResponse
) {
responseQueue.push({
event,
...parseJson
});
} else if (event === SseResponseEventEnum.flowNodeStatus) {
onMessage({
event,
...parseJson
@@ -182,6 +190,9 @@ export const streamFetch = ({
} else if (event === SseResponseEventEnum.flowResponses && Array.isArray(parseJson)) {
responseData = parseJson;
} else if (event === SseResponseEventEnum.error) {
if (parseJson.statusText === TeamErrEnum.aiPointsNotEnough) {
useSystemStore.getState().setIsNotSufficientModal(true);
}
errMsg = getErrText(parseJson, '流响应错误');
}
},

View File

@@ -6,6 +6,8 @@ import axios, {
} from 'axios';
import { clearToken, getToken } from '@/web/support/user/auth';
import { TOKEN_ERROR_CODE } from '@fastgpt/global/common/error/errorCode';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
import { useSystemStore } from '../system/useSystemStore';
interface ConfigType {
headers?: { [key: string]: string };
@@ -100,7 +102,9 @@ function responseError(err: any) {
if (err?.code in TOKEN_ERROR_CODE) {
clearToken();
if (window.location.pathname !== '/chat/share') {
if (
!(window.location.pathname === '/chat/share' || window.location.pathname === '/chat/team')
) {
window.location.replace(
`/login?lastRoute=${encodeURIComponent(location.pathname + location.search)}`
);
@@ -108,6 +112,10 @@ function responseError(err: any) {
return Promise.reject({ message: '无权操作' });
}
if (err?.statusText === TeamErrEnum.aiPointsNotEnough) {
useSystemStore.getState().setIsNotSufficientModal(true);
return Promise.reject(err);
}
if (err?.response?.data) {
return Promise.reject(err?.response?.data);
}

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useDisclosure, Button, ModalBody, ModalFooter } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import MyModal from '@/components/MyModal';
import MyModal from '@fastgpt/web/components/common/MyModal';
export const useConfirm = (props?: {
title?: string;

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useRef } from 'react';
import { ModalFooter, ModalBody, Input, useDisclosure, Button, Box } from '@chakra-ui/react';
import MyModal from '@/components/MyModal';
import MyModal from '@fastgpt/web/components/common/MyModal';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useTranslation } from 'next-i18next';

View File

@@ -24,11 +24,16 @@ export const useRequest = ({ successToast, errorToast, onSuccess, onError, ...pr
},
onError(err: any, variables: void, context: unknown) {
onError?.(err, variables, context);
errorToast &&
toast({
title: t(getErrText(err, errorToast)),
status: 'error'
});
if (errorToast !== undefined) {
const errText = t(getErrText(err, errorToast || ''));
if (errText) {
toast({
title: errText,
status: 'error'
});
}
}
}
});

View File

@@ -13,7 +13,6 @@ import type {
import { InitDateResponse } from '@/global/common/api/systemRes';
import { FastGPTFeConfigsType } from '@fastgpt/global/common/system/types';
import { SubPlanType } from '@fastgpt/global/support/wallet/sub/type';
import { AppSimpleEditConfigTemplateType } from '@fastgpt/global/core/app/type';
type LoginStoreType = { provider: `${OAuthEnum}`; lastRoute: string; state: string };
@@ -33,6 +32,9 @@ type State = {
gitStar: number;
loadGitStar: () => Promise<void>;
isNotSufficientModal: boolean;
setIsNotSufficientModal: (val: boolean) => void;
feConfigs: FastGPTFeConfigsType;
subPlans?: SubPlanType;
systemVersion: string;
@@ -42,7 +44,6 @@ type State = {
audioSpeechModelList: AudioSpeechModelType[];
reRankModelList: ReRankModelItemType[];
whisperModel?: WhisperModelType;
simpleModeTemplates: AppSimpleEditConfigTemplateType[];
initStaticData: (e: InitDateResponse) => void;
};
@@ -101,6 +102,13 @@ export const useSystemStore = create<State>()(
} catch (error) {}
},
isNotSufficientModal: false,
setIsNotSufficientModal(val: boolean) {
set((state) => {
state.isNotSufficientModal = val;
});
},
feConfigs: {},
subPlans: undefined,
systemVersion: '0.0.0',
@@ -110,7 +118,6 @@ export const useSystemStore = create<State>()(
audioSpeechModelList: [],
reRankModelList: [],
whisperModel: undefined,
simpleModeTemplates: [],
initStaticData(res) {
set((state) => {
state.feConfigs = res.feConfigs || {};
@@ -123,8 +130,6 @@ export const useSystemStore = create<State>()(
state.audioSpeechModelList = res.audioSpeechModels ?? state.audioSpeechModelList;
state.reRankModelList = res.reRankModels ?? state.reRankModelList;
state.whisperModel = res.whisperModel;
state.simpleModeTemplates = res.simpleModeTemplates;
});
}
})),