Skip to content

Commit

Permalink
4.8-fix (#1305)
Browse files Browse the repository at this point in the history
* fix if-else find variables (#92)

* fix if-else find variables

* change workflow output type

* fix tooltip style

* fix

* 4.8 (#93)

* api middleware

* perf: app version histories

* faq

* perf: value type show

* fix: ts

* fix: Run the same node multiple times

* feat: auto save workflow

* perf: auto save workflow

---------

Co-authored-by: heheer <[email protected]>
  • Loading branch information
c121914yu and newfish-cmyk authored Apr 27, 2024
1 parent c8412e7 commit d407e87
Show file tree
Hide file tree
Showing 87 changed files with 1,576 additions and 1,748 deletions.
29 changes: 29 additions & 0 deletions .vscode/nextapi.code-snippets
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
// Place your FastGPT 工作区 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
"Next api template": {
"scope": "javascript,typescript",
"prefix": "nextapi",
"body": [
"import type { NextApiRequest, NextApiResponse } from 'next';",
"import { NextAPI } from '@/service/middle/entry';",
"",
"type Props = {};",
"",
"type Response = {};",
"",
"async function handler(req: NextApiRequest, res: NextApiResponse<any>): Promise<{}> {",
" $1",
" return {}",
"}",
"",
"export default NextAPI(handler);"
],
"description": "FastGPT Next API template"
}
}
12 changes: 10 additions & 2 deletions docSite/content/docs/development/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ images: []

1. `docker ps -a` 查看所有容器运行状态,检查是否全部 running,如有异常,尝试`docker logs 容器名`查看对应日志。
2. 容器都运行正常的,`docker logs 容器名` 查看报错日志
3. 无法解决时,可以找找[Issue](https://github.com/labring/FastGPT/issues),或新提 Issue,私有部署错误,务必提供详细的日志,否则很难排查。
3. 带有`requestId`的,都是 OneAPI 提示错误,大部分都是因为模型接口报错。
4. 无法解决时,可以找找[Issue](https://github.com/labring/FastGPT/issues),或新提 Issue,私有部署错误,务必提供详细的日志,否则很难排查。




## 二、通用问题
Expand Down Expand Up @@ -90,4 +93,9 @@ FastGPT 模型配置文件中的 model 必须与 OneAPI 渠道中的模型对应

OneAPI 的 API Key 配置错误,需要修改`OPENAI_API_KEY`环境变量,并重启容器(先 docker-compose down 然后再 docker-compose up -d 运行一次)。

可以`exec`进入容器,`env`查看环境变量是否生效。
可以`exec`进入容器,`env`查看环境变量是否生效。

### bad_response_status_code bad response status code 503

1. 模型服务不可用
2. ....
1 change: 1 addition & 0 deletions packages/global/common/string/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cronParser from 'cron-parser';
export const formatTime2YMDHM = (time?: Date) =>
time ? dayjs(time).format('YYYY-MM-DD HH:mm') : '';
export const formatTime2YMD = (time?: Date) => (time ? dayjs(time).format('YYYY-MM-DD') : '');
export const formatTime2HM = (time: Date = new Date()) => dayjs(time).format('HH:mm');

/* cron time parse */
export const cronParser2Fields = (cronString: string) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/global/core/app/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { VariableInputEnum } from '../workflow/constants';
import { SelectedDatasetType } from '../workflow/api';
import { DatasetSearchModeEnum } from '../dataset/constants';
import { TeamTagSchema as TeamTagsSchemaType } from '@fastgpt/global/support/user/team/type.d';
import { StoreEdgeItemType } from 'core/workflow/type/edge';
import { StoreEdgeItemType } from '../workflow/type/edge';

export interface AppSchema {
_id: string;
Expand All @@ -18,6 +18,7 @@ export interface AppSchema {
avatar: string;
intro: string;
updateTime: number;

modules: StoreNodeItemType[];
edges: StoreEdgeItemType[];

Expand Down
9 changes: 9 additions & 0 deletions packages/global/core/app/version.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { StoreNodeItemType } from '../workflow/type';
import { StoreEdgeItemType } from '../workflow/type/edge';

export type AppVersionSchemaType = {
appId: string;
time: Date;
nodes: StoreNodeItemType[];
edges: StoreEdgeItemType[];
};
13 changes: 9 additions & 4 deletions packages/global/core/workflow/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@ export enum WorkflowIOValueTypeEnum {
string = 'string',
number = 'number',
boolean = 'boolean',
object = 'object',
arrayString = 'arrayString',
arrayNumber = 'arrayNumber',
arrayBoolean = 'arrayBoolean',
arrayObject = 'arrayObject',
any = 'any',

chatHistory = 'chatHistory',
datasetQuote = 'datasetQuote',

dynamic = 'dynamic',

// plugin special type
selectApp = 'selectApp',
selectDataset = 'selectDataset',

// tool
tools = 'tools'
selectDataset = 'selectDataset'
}

/* reg: modulename key */
Expand Down Expand Up @@ -173,3 +176,5 @@ export enum RuntimeEdgeStatusEnum {
'active' = 'active',
'skipped' = 'skipped'
}

export const VARIABLE_NODE_ID = 'VARIABLE_NODE_ID';
2 changes: 1 addition & 1 deletion packages/global/core/workflow/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { FlowNodeTypeEnum } from '../node/constant';
import { StoreNodeItemType } from '../type';
import { StoreEdgeItemType } from '../type/edge';
import { RuntimeEdgeItemType, RuntimeNodeItemType } from './type';
import { VARIABLE_NODE_ID } from '../../../../../projects/app/src/web/core/workflow/constants/index';
import { VARIABLE_NODE_ID } from '../constants';

export const initWorkflowEdgeStatus = (edges: StoreEdgeItemType[]): RuntimeEdgeItemType[] => {
return (
Expand Down
24 changes: 17 additions & 7 deletions packages/global/core/workflow/template/system/datasetConcat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,26 @@ import {
NodeOutputKeyEnum,
FlowNodeTemplateTypeEnum
} from '../../constants';
import { Input_Template_Dataset_Quote } from '../input';
import { getNanoid } from '../../../../common/string/tools';
import { getHandleConfig } from '../utils';
import { FlowNodeInputItemType } from '../../type/io.d';

export const getOneQuoteInputTemplate = (key = getNanoid()): FlowNodeInputItemType => ({
...Input_Template_Dataset_Quote,
const defaultQuoteKey = 'defaultQuoteKey';

export const getOneQuoteInputTemplate = ({
key = getNanoid(),
index
}: {
key?: string;
index: number;
}): FlowNodeInputItemType => ({
key,
renderTypeList: [FlowNodeInputTypeEnum.custom],
description: ''
renderTypeList: [FlowNodeInputTypeEnum.reference],
label: `引用${index}`,
debugLabel: '知识库引用',
canEdit: key !== defaultQuoteKey,
description: '',
valueType: WorkflowIOValueTypeEnum.datasetQuote
});

export const DatasetConcatModule: FlowNodeTemplateType = {
Expand All @@ -37,15 +47,15 @@ export const DatasetConcatModule: FlowNodeTemplateType = {
key: NodeInputKeyEnum.datasetMaxTokens,
renderTypeList: [FlowNodeInputTypeEnum.custom],
label: '最大 Tokens',
value: 1500,
value: 3000,
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'customComponent',
renderTypeList: [FlowNodeInputTypeEnum.custom],
label: ''
},
getOneQuoteInputTemplate()
getOneQuoteInputTemplate({ key: defaultQuoteKey, index: 1 })
],
outputs: [
{
Expand Down
25 changes: 9 additions & 16 deletions packages/service/common/middle/cors.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import type { NextApiResponse, NextApiHandler, NextApiRequest } from 'next';
import type { NextApiResponse, NextApiRequest } from 'next';
import NextCors from 'nextjs-cors';

export function withNextCors(handler: NextApiHandler): NextApiHandler {
return async function nextApiHandlerWrappedWithNextCors(
req: NextApiRequest,
res: NextApiResponse
) {
const methods = ['GET', 'eHEAD', 'PUT', 'PATCH', 'POST', 'DELETE'];
const origin = req.headers.origin;
await NextCors(req, res, {
methods,
origin: origin,
optionsSuccessStatus: 200
});

return handler(req, res);
};
export async function withNextCors(req: NextApiRequest, res: NextApiResponse) {
const methods = ['GET', 'eHEAD', 'PUT', 'PATCH', 'POST', 'DELETE'];
const origin = req.headers.origin;
await NextCors(req, res, {
methods,
origin: origin,
optionsSuccessStatus: 200
});
}
5 changes: 3 additions & 2 deletions packages/service/common/response/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ export const jsonRes = <T = any>(
message?: string;
data?: T;
error?: any;
url?: string;
}
) => {
const { code = 200, message = '', data = null, error } = props || {};
const { code = 200, message = '', data = null, error, url } = props || {};

const errResponseKey = typeof error === 'string' ? error : error?.message;
// Specified error
Expand All @@ -47,7 +48,7 @@ export const jsonRes = <T = any>(
msg = error?.error?.message;
}

addLog.error(`response error: ${msg}`, error);
addLog.error(`Api response error: ${url}, ${msg}`, error);
}

res.status(code).json({
Expand Down
11 changes: 10 additions & 1 deletion packages/service/common/vectorStore/pg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,16 @@ class PgClass {
}
async query<T extends QueryResultRow = any>(sql: string) {
const pg = await connectPg();
return pg.query<T>(sql);
const start = Date.now();
return pg.query<T>(sql).then((res) => {
const time = Date.now() - start;

if (time > 300) {
addLog.warn(`pg query time: ${time}ms, sql: ${sql}`);
}

return res;
});
}
}

Expand Down
65 changes: 65 additions & 0 deletions packages/service/core/app/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { AppSchema } from '@fastgpt/global/core/app/type';
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { getLLMModel } from '../ai/model';
import { MongoAppVersion } from './versionSchema';

export const beforeUpdateAppFormat = <T extends AppSchema['modules'] | undefined>({
nodes
}: {
nodes: T;
}) => {
if (nodes) {
let maxTokens = 3000;

nodes.forEach((item) => {
if (
item.flowNodeType === FlowNodeTypeEnum.chatNode ||
item.flowNodeType === FlowNodeTypeEnum.tools
) {
const model =
item.inputs.find((item) => item.key === NodeInputKeyEnum.aiModel)?.value || '';
const chatModel = getLLMModel(model);
const quoteMaxToken = chatModel.quoteMaxToken || 3000;

maxTokens = Math.max(maxTokens, quoteMaxToken);
}
});

nodes.forEach((item) => {
if (item.flowNodeType === FlowNodeTypeEnum.datasetSearchNode) {
item.inputs.forEach((input) => {
if (input.key === NodeInputKeyEnum.datasetMaxTokens) {
const val = input.value as number;
if (val > maxTokens) {
input.value = maxTokens;
}
}
});
}
});
}

return {
nodes
};
};

export const getAppLatestVersion = async (appId: string, app?: AppSchema) => {
const version = await MongoAppVersion.findOne({
appId
}).sort({
time: -1
});

if (version) {
return {
nodes: version.nodes,
edges: version.edges
};
}
return {
nodes: app?.modules || [],
edges: app?.edges || []
};
};
6 changes: 4 additions & 2 deletions packages/service/core/app/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
TeamMemberCollectionName
} from '@fastgpt/global/support/user/team/constant';

export const appCollectionName = 'apps';
export const AppCollectionName = 'apps';

const AppSchema = new Schema({
teamId: {
Expand Down Expand Up @@ -46,6 +46,8 @@ const AppSchema = new Schema({
type: Date,
default: () => new Date()
},

// tmp store
modules: {
type: Array,
default: []
Expand Down Expand Up @@ -92,6 +94,6 @@ try {
}

export const MongoApp: Model<AppType> =
models[appCollectionName] || model(appCollectionName, AppSchema);
models[AppCollectionName] || model(AppCollectionName, AppSchema);

MongoApp.syncIndexes();
36 changes: 36 additions & 0 deletions packages/service/core/app/versionSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { connectionMongo, type Model } from '../../common/mongo';
const { Schema, model, models } = connectionMongo;
import { AppVersionSchemaType } from '@fastgpt/global/core/app/version';

export const AppVersionCollectionName = 'app.versions';

const AppVersionSchema = new Schema({
appId: {
type: Schema.Types.ObjectId,
ref: AppVersionCollectionName,
required: true
},
time: {
type: Date,
default: () => new Date()
},
nodes: {
type: Array,
default: []
},
edges: {
type: Array,
default: []
}
});

try {
AppVersionSchema.index({ appId: 1, time: -1 });
} catch (error) {
console.log(error);
}

export const MongoAppVersion: Model<AppVersionSchemaType> =
models[AppVersionCollectionName] || model(AppVersionCollectionName, AppVersionSchema);

MongoAppVersion.syncIndexes();
4 changes: 2 additions & 2 deletions packages/service/core/chat/chatItemSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
TeamCollectionName,
TeamMemberCollectionName
} from '@fastgpt/global/support/user/team/constant';
import { appCollectionName } from '../app/schema';
import { AppCollectionName } from '../app/schema';
import { userCollectionName } from '../../support/user/schema';
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
Expand Down Expand Up @@ -40,7 +40,7 @@ const ChatItemSchema = new Schema({
},
appId: {
type: Schema.Types.ObjectId,
ref: appCollectionName,
ref: AppCollectionName,
required: true
},
time: {
Expand Down
Loading

0 comments on commit d407e87

Please sign in to comment.