mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 13:03:50 +00:00
4.8 test fix (#1397)
* adapt v1 chat init * adapt v1 chat init * adapt v1 chat init * perf: message input line; fix: http request un stream * perf: message input line; fix: http request un stream * perf: message input line; fix: http request un stream * perf: error tip
This commit is contained in:
@@ -2,7 +2,7 @@ import { ErrType } from '../errorCode';
|
|||||||
|
|
||||||
/* dataset: 502000 */
|
/* dataset: 502000 */
|
||||||
export enum AppErrEnum {
|
export enum AppErrEnum {
|
||||||
unExist = 'unExist',
|
unExist = 'appUnExist',
|
||||||
unAuthApp = 'unAuthApp'
|
unAuthApp = 'unAuthApp'
|
||||||
}
|
}
|
||||||
const appErrList = [
|
const appErrList = [
|
||||||
|
@@ -2,8 +2,8 @@ import { ErrType } from '../errorCode';
|
|||||||
|
|
||||||
/* dataset: 506000 */
|
/* dataset: 506000 */
|
||||||
export enum OpenApiErrEnum {
|
export enum OpenApiErrEnum {
|
||||||
unExist = 'unExist',
|
unExist = 'openapiUnExist',
|
||||||
unAuth = 'unAuth'
|
unAuth = 'openapiUnAuth'
|
||||||
}
|
}
|
||||||
const errList = [
|
const errList = [
|
||||||
{
|
{
|
||||||
|
@@ -2,7 +2,7 @@ import { ErrType } from '../errorCode';
|
|||||||
|
|
||||||
/* dataset: 505000 */
|
/* dataset: 505000 */
|
||||||
export enum OutLinkErrEnum {
|
export enum OutLinkErrEnum {
|
||||||
unExist = 'unExist',
|
unExist = 'outlinkUnExist',
|
||||||
unAuthLink = 'unAuthLink',
|
unAuthLink = 'unAuthLink',
|
||||||
linkUnInvalid = 'linkUnInvalid',
|
linkUnInvalid = 'linkUnInvalid',
|
||||||
|
|
||||||
|
@@ -2,8 +2,8 @@ import { ErrType } from '../errorCode';
|
|||||||
|
|
||||||
/* dataset: 507000 */
|
/* dataset: 507000 */
|
||||||
export enum PluginErrEnum {
|
export enum PluginErrEnum {
|
||||||
unExist = 'unExist',
|
unExist = 'pluginUnExist',
|
||||||
unAuth = 'unAuth'
|
unAuth = 'pluginUnAuth'
|
||||||
}
|
}
|
||||||
const errList = [
|
const errList = [
|
||||||
{
|
{
|
||||||
|
@@ -15,7 +15,7 @@ export const VariableUpdateNode: FlowNodeTemplateType = {
|
|||||||
targetHandle: getHandleConfig(true, true, true, true),
|
targetHandle: getHandleConfig(true, true, true, true),
|
||||||
avatar: '/imgs/workflow/variable.png',
|
avatar: '/imgs/workflow/variable.png',
|
||||||
name: '变量更新',
|
name: '变量更新',
|
||||||
intro: '可以更新指定节点的输出值和全局变量',
|
intro: '可以更新指定节点的输出值或更新全局变量',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
isTool: false,
|
isTool: false,
|
||||||
inputs: [
|
inputs: [
|
||||||
|
@@ -290,7 +290,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
runtimeNodes,
|
runtimeNodes,
|
||||||
runtimeEdges,
|
runtimeEdges,
|
||||||
params,
|
params,
|
||||||
mode: 'test'
|
mode: props.mode === 'debug' ? 'test' : props.mode
|
||||||
};
|
};
|
||||||
|
|
||||||
// run module
|
// run module
|
||||||
|
@@ -45,6 +45,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
|||||||
detail,
|
detail,
|
||||||
appId,
|
appId,
|
||||||
chatId,
|
chatId,
|
||||||
|
stream,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
variables,
|
variables,
|
||||||
node: { outputs },
|
node: { outputs },
|
||||||
@@ -132,7 +133,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
|||||||
results[key] = valueTypeFormat(formatResponse[key], output.valueType);
|
results[key] = valueTypeFormat(formatResponse[key], output.valueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof formatResponse[NodeOutputKeyEnum.answerText] === 'string') {
|
if (stream && typeof formatResponse[NodeOutputKeyEnum.answerText] === 'string') {
|
||||||
responseWrite({
|
responseWrite({
|
||||||
res,
|
res,
|
||||||
event: detail ? SseResponseEventEnum.fastAnswer : undefined,
|
event: detail ? SseResponseEventEnum.fastAnswer : undefined,
|
||||||
|
@@ -85,7 +85,22 @@
|
|||||||
"x": 1607.7142331269126,
|
"x": 1607.7142331269126,
|
||||||
"y": -151.8669210746189
|
"y": -151.8669210746189
|
||||||
},
|
},
|
||||||
"inputs": [],
|
"inputs": [
|
||||||
|
{
|
||||||
|
"key": "text",
|
||||||
|
"valueType": "string",
|
||||||
|
"label": "text",
|
||||||
|
"renderTypeList": ["reference"],
|
||||||
|
"description": "",
|
||||||
|
"canEdit": true,
|
||||||
|
"editField": {
|
||||||
|
"key": true,
|
||||||
|
"description": true,
|
||||||
|
"valueType": true
|
||||||
|
},
|
||||||
|
"value": ["CRT7oIEU8v2P", "pYKS0LB9gAr3"]
|
||||||
|
}
|
||||||
|
],
|
||||||
"outputs": []
|
"outputs": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -190,6 +205,13 @@
|
|||||||
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
|
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
|
||||||
"valueType": "any",
|
"valueType": "any",
|
||||||
"type": "static"
|
"type": "static"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "pYKS0LB9gAr3",
|
||||||
|
"type": "dynamic",
|
||||||
|
"key": "text",
|
||||||
|
"valueType": "string",
|
||||||
|
"label": "text"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -357,9 +357,16 @@ const MessageInput = ({
|
|||||||
// enter send.(pc or iframe && enter and unPress shift)
|
// enter send.(pc or iframe && enter and unPress shift)
|
||||||
const isEnter = e.keyCode === 13;
|
const isEnter = e.keyCode === 13;
|
||||||
if (isEnter && TextareaDom.current && (e.ctrlKey || e.altKey)) {
|
if (isEnter && TextareaDom.current && (e.ctrlKey || e.altKey)) {
|
||||||
TextareaDom.current.value += '\n';
|
// Add a new line
|
||||||
|
const index = TextareaDom.current.selectionStart;
|
||||||
|
const val = TextareaDom.current.value;
|
||||||
|
TextareaDom.current.value = `${val.slice(0, index)}\n${val.slice(index)}`;
|
||||||
|
TextareaDom.current.selectionStart = index + 1;
|
||||||
|
TextareaDom.current.selectionEnd = index + 1;
|
||||||
|
|
||||||
TextareaDom.current.style.height = textareaMinH;
|
TextareaDom.current.style.height = textareaMinH;
|
||||||
TextareaDom.current.style.height = `${TextareaDom.current.scrollHeight}px`;
|
TextareaDom.current.style.height = `${TextareaDom.current.scrollHeight}px`;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -487,7 +487,6 @@ const WorkflowContextProvider = ({
|
|||||||
// 3. Set entry node status to running
|
// 3. Set entry node status to running
|
||||||
entryNodes.forEach((node) => {
|
entryNodes.forEach((node) => {
|
||||||
if (runtimeNodeStatus[node.nodeId] !== 'wait') {
|
if (runtimeNodeStatus[node.nodeId] !== 'wait') {
|
||||||
console.log(node.name);
|
|
||||||
onChangeNode({
|
onChangeNode({
|
||||||
nodeId: node.nodeId,
|
nodeId: node.nodeId,
|
||||||
type: 'attr',
|
type: 'attr',
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { jsonRes } from '@fastgpt/service/common/response';
|
import { jsonRes } from '@fastgpt/service/common/response';
|
||||||
import { connectToDatabase } from '@/service/mongo';
|
|
||||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||||
import { getGuideModule, replaceAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
import { getGuideModule, replaceAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
||||||
import { getChatModelNameListByModules } from '@/service/core/app/workflow';
|
import { getChatModelNameListByModules } from '@/service/core/app/workflow';
|
||||||
@@ -10,78 +9,73 @@ import { getChatItems } from '@fastgpt/service/core/chat/controller';
|
|||||||
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
|
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
|
||||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||||
import { getAppLatestVersion } from '@fastgpt/service/core/app/controller';
|
import { getAppLatestVersion } from '@fastgpt/service/core/app/controller';
|
||||||
|
import { NextAPI } from '@/service/middle/entry';
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
async function handler(
|
||||||
try {
|
req: NextApiRequest,
|
||||||
await connectToDatabase();
|
res: NextApiResponse
|
||||||
|
): Promise<InitChatResponse | void> {
|
||||||
|
let { appId, chatId, loadCustomFeedbacks } = req.query as InitChatProps;
|
||||||
|
|
||||||
let { appId, chatId, loadCustomFeedbacks } = req.query as InitChatProps;
|
if (!appId) {
|
||||||
|
return jsonRes(res, {
|
||||||
if (!appId) {
|
code: 501,
|
||||||
return jsonRes(res, {
|
message: "You don't have an app yet"
|
||||||
code: 501,
|
|
||||||
message: "You don't have an app yet"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// auth app permission
|
|
||||||
const [{ app, tmbId }, chat] = await Promise.all([
|
|
||||||
authApp({
|
|
||||||
req,
|
|
||||||
authToken: true,
|
|
||||||
appId,
|
|
||||||
per: 'r'
|
|
||||||
}),
|
|
||||||
chatId ? MongoChat.findOne({ appId, chatId }) : undefined
|
|
||||||
]);
|
|
||||||
|
|
||||||
// auth chat permission
|
|
||||||
if (chat && !app.canWrite && String(tmbId) !== String(chat?.tmbId)) {
|
|
||||||
throw new Error(ChatErrEnum.unAuthChat);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get app and history
|
|
||||||
const [{ history }, { nodes }] = await Promise.all([
|
|
||||||
getChatItems({
|
|
||||||
appId,
|
|
||||||
chatId,
|
|
||||||
limit: 30,
|
|
||||||
field: `dataId obj value adminFeedback userBadFeedback userGoodFeedback ${
|
|
||||||
DispatchNodeResponseKeyEnum.nodeResponse
|
|
||||||
} ${loadCustomFeedbacks ? 'customFeedbacks' : ''}`
|
|
||||||
}),
|
|
||||||
getAppLatestVersion(app._id, app)
|
|
||||||
]);
|
|
||||||
|
|
||||||
jsonRes<InitChatResponse>(res, {
|
|
||||||
data: {
|
|
||||||
chatId,
|
|
||||||
appId,
|
|
||||||
title: chat?.title || '新对话',
|
|
||||||
userAvatar: undefined,
|
|
||||||
variables: chat?.variables || {},
|
|
||||||
history,
|
|
||||||
app: {
|
|
||||||
userGuideModule: replaceAppChatConfig({
|
|
||||||
node: getGuideModule(nodes),
|
|
||||||
variableList: chat?.variableList,
|
|
||||||
welcomeText: chat?.welcomeText
|
|
||||||
}),
|
|
||||||
chatModels: getChatModelNameListByModules(nodes),
|
|
||||||
name: app.name,
|
|
||||||
avatar: app.avatar,
|
|
||||||
intro: app.intro
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
jsonRes(res, {
|
|
||||||
code: 500,
|
|
||||||
error: err
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auth app permission
|
||||||
|
const [{ app, tmbId }, chat] = await Promise.all([
|
||||||
|
authApp({
|
||||||
|
req,
|
||||||
|
authToken: true,
|
||||||
|
appId,
|
||||||
|
per: 'r'
|
||||||
|
}),
|
||||||
|
chatId ? MongoChat.findOne({ appId, chatId }) : undefined
|
||||||
|
]);
|
||||||
|
|
||||||
|
// auth chat permission
|
||||||
|
if (chat && !app.canWrite && String(tmbId) !== String(chat?.tmbId)) {
|
||||||
|
throw new Error(ChatErrEnum.unAuthChat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get app and history
|
||||||
|
const [{ history }, { nodes }] = await Promise.all([
|
||||||
|
getChatItems({
|
||||||
|
appId,
|
||||||
|
chatId,
|
||||||
|
limit: 30,
|
||||||
|
field: `dataId obj value adminFeedback userBadFeedback userGoodFeedback ${
|
||||||
|
DispatchNodeResponseKeyEnum.nodeResponse
|
||||||
|
} ${loadCustomFeedbacks ? 'customFeedbacks' : ''}`
|
||||||
|
}),
|
||||||
|
getAppLatestVersion(app._id, app)
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
chatId,
|
||||||
|
appId,
|
||||||
|
title: chat?.title || '新对话',
|
||||||
|
userAvatar: undefined,
|
||||||
|
variables: chat?.variables || {},
|
||||||
|
history,
|
||||||
|
app: {
|
||||||
|
userGuideModule: replaceAppChatConfig({
|
||||||
|
node: getGuideModule(nodes),
|
||||||
|
variableList: chat?.variableList,
|
||||||
|
welcomeText: chat?.welcomeText
|
||||||
|
}),
|
||||||
|
chatModels: getChatModelNameListByModules(nodes),
|
||||||
|
name: app.name,
|
||||||
|
avatar: app.avatar,
|
||||||
|
intro: app.intro
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default NextAPI(handler);
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
responseLimit: '10mb'
|
responseLimit: '10mb'
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { connectToDatabase } from '@/service/mongo';
|
|
||||||
import { jsonRes } from '@fastgpt/service/common/response';
|
|
||||||
import { pushChatUsage } from '@/service/support/wallet/usage/push';
|
import { pushChatUsage } from '@/service/support/wallet/usage/push';
|
||||||
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||||
@@ -9,8 +7,12 @@ import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
|||||||
import { getUserChatInfoAndAuthTeamPoints } from '@/service/support/permission/auth/team';
|
import { getUserChatInfoAndAuthTeamPoints } from '@/service/support/permission/auth/team';
|
||||||
import { PostWorkflowDebugProps, PostWorkflowDebugResponse } from '@/global/core/workflow/api';
|
import { PostWorkflowDebugProps, PostWorkflowDebugResponse } from '@/global/core/workflow/api';
|
||||||
import { authPluginCrud } from '@fastgpt/service/support/permission/auth/plugin';
|
import { authPluginCrud } from '@fastgpt/service/support/permission/auth/plugin';
|
||||||
|
import { NextAPI } from '@/service/middle/entry';
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
async function handler(
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse
|
||||||
|
): Promise<PostWorkflowDebugResponse> {
|
||||||
const {
|
const {
|
||||||
nodes = [],
|
nodes = [],
|
||||||
edges = [],
|
edges = [],
|
||||||
@@ -18,72 +20,65 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
appId,
|
appId,
|
||||||
pluginId
|
pluginId
|
||||||
} = req.body as PostWorkflowDebugProps;
|
} = req.body as PostWorkflowDebugProps;
|
||||||
try {
|
|
||||||
await connectToDatabase();
|
|
||||||
if (!nodes) {
|
|
||||||
throw new Error('Prams Error');
|
|
||||||
}
|
|
||||||
if (!Array.isArray(nodes)) {
|
|
||||||
throw new Error('Nodes is not array');
|
|
||||||
}
|
|
||||||
if (!Array.isArray(edges)) {
|
|
||||||
throw new Error('Edges is not array');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* user auth */
|
if (!nodes) {
|
||||||
const [{ teamId, tmbId }] = await Promise.all([
|
throw new Error('Prams Error');
|
||||||
authCert({
|
|
||||||
req,
|
|
||||||
authToken: true
|
|
||||||
}),
|
|
||||||
appId && authApp({ req, authToken: true, appId, per: 'r' }),
|
|
||||||
pluginId && authPluginCrud({ req, authToken: true, pluginId, per: 'r' })
|
|
||||||
]);
|
|
||||||
|
|
||||||
// auth balance
|
|
||||||
const { user } = await getUserChatInfoAndAuthTeamPoints(tmbId);
|
|
||||||
|
|
||||||
/* start process */
|
|
||||||
const { flowUsages, flowResponses, debugResponse } = await dispatchWorkFlow({
|
|
||||||
res,
|
|
||||||
mode: 'debug',
|
|
||||||
teamId,
|
|
||||||
tmbId,
|
|
||||||
user,
|
|
||||||
appId,
|
|
||||||
runtimeNodes: nodes,
|
|
||||||
runtimeEdges: edges,
|
|
||||||
variables,
|
|
||||||
query: [],
|
|
||||||
histories: [],
|
|
||||||
stream: false,
|
|
||||||
detail: true,
|
|
||||||
maxRunTimes: 200
|
|
||||||
});
|
|
||||||
|
|
||||||
pushChatUsage({
|
|
||||||
appName: '工作流Debug',
|
|
||||||
appId,
|
|
||||||
teamId,
|
|
||||||
tmbId,
|
|
||||||
source: UsageSourceEnum.fastgpt,
|
|
||||||
flowUsages
|
|
||||||
});
|
|
||||||
|
|
||||||
jsonRes<PostWorkflowDebugResponse>(res, {
|
|
||||||
data: {
|
|
||||||
...debugResponse,
|
|
||||||
flowResponses
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err: any) {
|
|
||||||
jsonRes(res, {
|
|
||||||
code: 500,
|
|
||||||
error: err
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
if (!Array.isArray(nodes)) {
|
||||||
|
throw new Error('Nodes is not array');
|
||||||
|
}
|
||||||
|
if (!Array.isArray(edges)) {
|
||||||
|
throw new Error('Edges is not array');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* user auth */
|
||||||
|
const [{ teamId, tmbId }] = await Promise.all([
|
||||||
|
authCert({
|
||||||
|
req,
|
||||||
|
authToken: true
|
||||||
|
}),
|
||||||
|
appId && authApp({ req, authToken: true, appId, per: 'r' }),
|
||||||
|
pluginId && authPluginCrud({ req, authToken: true, pluginId, per: 'r' })
|
||||||
|
]);
|
||||||
|
|
||||||
|
// auth balance
|
||||||
|
const { user } = await getUserChatInfoAndAuthTeamPoints(tmbId);
|
||||||
|
|
||||||
|
/* start process */
|
||||||
|
const { flowUsages, flowResponses, debugResponse } = await dispatchWorkFlow({
|
||||||
|
res,
|
||||||
|
mode: 'debug',
|
||||||
|
teamId,
|
||||||
|
tmbId,
|
||||||
|
user,
|
||||||
|
appId,
|
||||||
|
runtimeNodes: nodes,
|
||||||
|
runtimeEdges: edges,
|
||||||
|
variables,
|
||||||
|
query: [],
|
||||||
|
histories: [],
|
||||||
|
stream: false,
|
||||||
|
detail: true,
|
||||||
|
maxRunTimes: 200
|
||||||
|
});
|
||||||
|
|
||||||
|
pushChatUsage({
|
||||||
|
appName: '工作流Debug',
|
||||||
|
appId,
|
||||||
|
teamId,
|
||||||
|
tmbId,
|
||||||
|
source: UsageSourceEnum.fastgpt,
|
||||||
|
flowUsages
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...debugResponse,
|
||||||
|
flowResponses
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default NextAPI(handler);
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
bodyParser: {
|
bodyParser: {
|
||||||
|
@@ -34,11 +34,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
|
|
||||||
if (!chatId || !chatItemId) {
|
if (!chatId || !chatItemId) {
|
||||||
return res.json({
|
return res.json({
|
||||||
[NodeOutputKeyEnum.answerText]: `\\n\\n**自动反馈调试**: "${customFeedback}"\\n\\n`
|
[NodeOutputKeyEnum.answerText]: `\\n\\n**自动反馈调试**: "${customFeedback}"\\n\\n`,
|
||||||
|
text: customFeedback
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.json({});
|
res.json({
|
||||||
|
text: customFeedback
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
res.status(500).send(getErrText(err));
|
res.status(500).send(getErrText(err));
|
||||||
|
Reference in New Issue
Block a user