mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 05:12:39 +00:00
@@ -20,6 +20,8 @@ CHAT_API_KEY=sk-xxxx
|
||||
MONGODB_URI=mongodb://username:password@0.0.0.0:27017/fastgpt?authSource=admin
|
||||
# PG 数据库连接参数
|
||||
PG_URL=postgresql://username:password@host:port/postgres
|
||||
# code sandbox url
|
||||
SANDBOX_URL=http://localhost:3001
|
||||
# 商业版地址
|
||||
PRO_URL=
|
||||
# 首页路径
|
||||
|
86
projects/app/Dockerfile
Normal file
86
projects/app/Dockerfile
Normal file
@@ -0,0 +1,86 @@
|
||||
# --------- install dependence -----------
|
||||
FROM node:18.17-alpine AS mainDeps
|
||||
WORKDIR /app
|
||||
|
||||
ARG proxy
|
||||
|
||||
RUN [ -z "$proxy" ] || sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
|
||||
RUN apk add --no-cache libc6-compat && npm install -g pnpm@8.6.0
|
||||
# if proxy exists, set proxy
|
||||
RUN [ -z "$proxy" ] || pnpm config set registry https://registry.npmmirror.com
|
||||
|
||||
# copy packages and one project
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
|
||||
COPY ./packages ./packages
|
||||
COPY ./projects/app/package.json ./projects/app/package.json
|
||||
|
||||
RUN [ -f pnpm-lock.yaml ] || (echo "Lockfile not found." && exit 1)
|
||||
|
||||
RUN pnpm i
|
||||
|
||||
# --------- builder -----------
|
||||
FROM node:18.17-alpine AS builder
|
||||
WORKDIR /app
|
||||
|
||||
ARG proxy
|
||||
|
||||
# copy common node_modules and one project node_modules
|
||||
COPY package.json pnpm-workspace.yaml .npmrc ./
|
||||
COPY --from=mainDeps /app/node_modules ./node_modules
|
||||
COPY --from=mainDeps /app/packages ./packages
|
||||
COPY ./projects/app ./projects/app
|
||||
COPY --from=mainDeps /app/projects/app/node_modules ./projects/app/node_modules
|
||||
|
||||
RUN [ -z "$proxy" ] || sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
|
||||
|
||||
RUN apk add --no-cache libc6-compat && npm install -g pnpm@8.6.0
|
||||
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
RUN pnpm --filter=app build
|
||||
|
||||
# --------- runner -----------
|
||||
FROM node:18.17-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ARG proxy
|
||||
|
||||
# create user and use it
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
RUN [ -z "$proxy" ] || sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
|
||||
RUN apk add --no-cache curl ca-certificates \
|
||||
&& update-ca-certificates
|
||||
|
||||
# copy running files
|
||||
COPY --from=builder /app/projects/app/public /app/projects/app/public
|
||||
COPY --from=builder /app/projects/app/next.config.js /app/projects/app/next.config.js
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/projects/app/.next/standalone /app/
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/projects/app/.next/static /app/projects/app/.next/static
|
||||
# copy server chunks
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/projects/app/.next/server/chunks /app/projects/app/.next/server/chunks
|
||||
# copy worker
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/projects/app/.next/server/worker /app/projects/app/.next/server/worker
|
||||
|
||||
# copy tiktoken but not copy ./node_modules/tiktoken/encoders
|
||||
COPY --from=mainDeps /app/node_modules/tiktoken ./node_modules/tiktoken
|
||||
RUN rm -rf ./node_modules/tiktoken/encoders
|
||||
|
||||
# copy package.json to version file
|
||||
COPY --from=builder /app/projects/app/package.json ./package.json
|
||||
# copy config
|
||||
COPY ./projects/app/data /app/data
|
||||
|
||||
RUN chown -R nextjs:nodejs /app/data
|
||||
|
||||
ENV NODE_ENV production
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
ENV PORT=3000
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
USER nextjs
|
||||
|
||||
ENV serverPath=./projects/app/server.js
|
||||
|
||||
ENTRYPOINT ["sh","-c","node --max-old-space-size=4096 ${serverPath}"]
|
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"Add new": "Add new",
|
||||
"App": "App",
|
||||
"Code editor": "Code edit",
|
||||
"Export": "Export",
|
||||
"Folder": "Folder",
|
||||
"Is open": "Opened",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
{
|
||||
"Field required": "Required"
|
||||
"Code": "Code",
|
||||
"Field required": "Required",
|
||||
"code": {
|
||||
"Reset template": "Reset template",
|
||||
"Reset template confirm": "Are you sure to restore the code template? Be careful to save the current code."
|
||||
},
|
||||
"response": {
|
||||
"Custom inputs": "Custom inputs",
|
||||
"Custom outputs": "Custom outputs"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"Add new": "新增",
|
||||
"App": "应用",
|
||||
"Code editor": "代码编辑",
|
||||
"Export": "导出",
|
||||
"Folder": "文件夹",
|
||||
"Is open": "是否开启",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
{
|
||||
"Field required": "必填"
|
||||
"Code": "代码",
|
||||
"Field required": "必填",
|
||||
"code": {
|
||||
"Reset template": "还原模板",
|
||||
"Reset template confirm": "确认还原代码模板?请注意保存当前代码。"
|
||||
},
|
||||
"response": {
|
||||
"Custom inputs": "自定义输入",
|
||||
"Custom outputs": "自定义输出"
|
||||
}
|
||||
}
|
||||
|
@@ -89,7 +89,7 @@ const nextConfig = {
|
||||
transpilePackages: ['@fastgpt/*', 'ahooks'],
|
||||
experimental: {
|
||||
// 优化 Server Components 的构建和运行,避免不必要的客户端打包。
|
||||
serverComponentsExternalPackages: ['mongoose', 'pg'],
|
||||
serverComponentsExternalPackages: ['mongoose', 'pg', '@node-rs/jieba'],
|
||||
outputFileTracingRoot: path.join(__dirname, '../../')
|
||||
}
|
||||
};
|
||||
|
24
projects/app/public/imgs/workflow/code.svg
Normal file
24
projects/app/public/imgs/workflow/code.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<svg t="1716862994060" class="icon" viewBox="0 0 1218 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4475"
|
||||
width="256" height="256">
|
||||
<path
|
||||
d="M1169.592417 975.469194V145.592417c0-53.383886-43.677725-97.061611-97.061611-97.061611H145.592417c-53.383886 0-97.061611 43.677725-97.061611 97.061611v829.876777h1121.061611z"
|
||||
fill="#7CDEDC" p-id="4476"></path>
|
||||
<path
|
||||
d="M1193.85782 975.469194V145.592417c0-66.899716-54.427299-121.327014-121.327014-121.327014H145.592417C78.692701 24.265403 24.265403 78.692701 24.265403 145.592417v854.14218h1169.592417v-24.265403z m-1121.061611 0V145.592417c0-40.139829 32.656379-72.796209 72.796208-72.796208h926.938389c40.139829 0 72.796209 32.656379 72.796208 72.796208v829.876777l24.265403-24.265403H48.530806l24.265403 24.265403z"
|
||||
fill="#6E6E96" p-id="4477"></path>
|
||||
<path d="M48.530806 237.800948h1145.327014v48.530806H48.530806z" fill="#6E6E96" p-id="4478"></path>
|
||||
<path
|
||||
d="M1072.530806 48.530806H145.592417c-53.383886 0-97.061611 43.677725-97.061611 97.061611v111.620853h1121.061611V145.592417c0-53.383886-43.677725-97.061611-97.061611-97.061611z"
|
||||
fill="#FFF491" p-id="4479"></path>
|
||||
<path
|
||||
d="M1072.530806 24.265403H145.592417C78.692701 24.265403 24.265403 78.692701 24.265403 145.592417v135.886256h1169.592417V145.592417c0-66.899716-54.427299-121.327014-121.327014-121.327014z m72.796208 121.327014v111.620853l24.265403-24.265403H48.530806l24.265403 24.265403V145.592417c0-40.139829 32.656379-72.796209 72.796208-72.796208h926.938389c40.139829 0 72.796209 32.656379 72.796208 72.796208zM374.725763 431.74946l-167.43128 167.436132L190.138844 616.341232l17.155639 17.15564 167.43128 167.43128 34.320986-34.31128-167.43128-167.43128v34.31128l167.43128-167.426427zM813.934408 466.070445l167.431279 167.426427v-34.31128l-167.431279 167.43128 34.311279 34.31128 167.43128-167.43128L1032.832607 616.341232l-17.15564-17.15564-167.43128-167.436132z"
|
||||
fill="#6E6E96" p-id="4480"></path>
|
||||
<path
|
||||
d="M531.412322 618.767773m-41.251185 0a41.251185 41.251185 0 1 0 82.50237 0 41.251185 41.251185 0 1 0-82.50237 0Z"
|
||||
fill="#6E6E96" p-id="4481"></path>
|
||||
<path
|
||||
d="M706.123223 618.767773m-41.251185 0a41.251185 41.251185 0 1 0 82.50237 0 41.251185 41.251185 0 1 0-82.50237 0Z"
|
||||
fill="#6E6E96" p-id="4482"></path>
|
||||
<path d="M72.796209 281.478673h1072.530805v53.383886H72.796209z" fill="#6E6E96" opacity=".15" p-id="4483"></path>
|
||||
<path d="M72.796209 189.270142h1072.530805v43.677725H72.796209z" fill="#6E6E96" opacity=".15" p-id="4484"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
@@ -1,5 +1,5 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Box, useTheme, Flex, Image } from '@chakra-ui/react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { Box, useTheme, Flex, Image, BoxProps } from '@chakra-ui/react';
|
||||
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
|
||||
@@ -12,42 +12,68 @@ import Markdown from '../Markdown';
|
||||
import { QuoteList } from './QuoteModal';
|
||||
import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import { formatNumber } from '@fastgpt/global/common/math/tools';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
|
||||
function RowRender({
|
||||
children,
|
||||
mb,
|
||||
label,
|
||||
...props
|
||||
}: { children: React.ReactNode; label: string } & BoxProps) {
|
||||
return (
|
||||
<Box mb={3}>
|
||||
<Box fontSize={['sm', 'md']} mb={mb} flex={'0 0 90px'}>
|
||||
{label}:
|
||||
</Box>
|
||||
<Box borderRadius={'sm'} fontSize={'sm'} bg={'myGray.50'} {...props}>
|
||||
{children}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
function Row({
|
||||
label,
|
||||
value,
|
||||
rawDom
|
||||
}: {
|
||||
label: string;
|
||||
value?: string | number | boolean;
|
||||
value?: string | number | boolean | object;
|
||||
rawDom?: React.ReactNode;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const val = value || rawDom;
|
||||
const strValue = `${value}`;
|
||||
const isCodeBlock = strValue.startsWith('~~~json');
|
||||
const isObject = typeof value === 'object';
|
||||
|
||||
return val !== undefined && val !== '' && val !== 'undefined' ? (
|
||||
<Box mb={3}>
|
||||
<Box fontSize={['sm', 'md']} mb={isCodeBlock ? 0 : 1} flex={'0 0 90px'}>
|
||||
{t(label)}:
|
||||
</Box>
|
||||
<Box
|
||||
borderRadius={'sm'}
|
||||
fontSize={'sm'}
|
||||
bg={'myGray.50'}
|
||||
{...(isCodeBlock
|
||||
? { transform: 'translateY(-3px)' }
|
||||
: value
|
||||
? { px: 3, py: 2, border: theme.borders.base }
|
||||
: {})}
|
||||
>
|
||||
{value && <Markdown source={strValue} />}
|
||||
const formatValue = useMemo(() => {
|
||||
if (isObject) {
|
||||
return `~~~json\n${JSON.stringify(value, null, 2)}`;
|
||||
}
|
||||
return `${value}`;
|
||||
}, [isObject, value]);
|
||||
|
||||
if (rawDom) {
|
||||
return (
|
||||
<RowRender label={label} mb={1}>
|
||||
{rawDom}
|
||||
</Box>
|
||||
</Box>
|
||||
) : null;
|
||||
</RowRender>
|
||||
);
|
||||
}
|
||||
|
||||
if (val === undefined || val === '' || val === 'undefined') return null;
|
||||
|
||||
return (
|
||||
<RowRender
|
||||
label={label}
|
||||
mb={isObject ? 0 : 1}
|
||||
{...(isObject
|
||||
? { transform: 'translateY(-3px)' }
|
||||
: value
|
||||
? { px: 3, py: 2, border: theme.borders.base }
|
||||
: {})}
|
||||
>
|
||||
<Markdown source={formatValue} />
|
||||
</RowRender>
|
||||
);
|
||||
}
|
||||
|
||||
const WholeResponseModal = ({
|
||||
@@ -98,6 +124,7 @@ export const ResponseBox = React.memo(function ResponseBox({
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const { workflowT } = useI18n();
|
||||
|
||||
const list = useMemo(
|
||||
() =>
|
||||
@@ -251,47 +278,26 @@ export const ResponseBox = React.memo(function ResponseBox({
|
||||
label={t('core.chat.response.module extract description')}
|
||||
value={activeModule?.extractDescription}
|
||||
/>
|
||||
{activeModule?.extractResult && (
|
||||
<Row
|
||||
label={t('core.chat.response.module extract result')}
|
||||
value={`~~~json\n${JSON.stringify(activeModule?.extractResult, null, 2)}`}
|
||||
/>
|
||||
)}
|
||||
<Row
|
||||
label={t('core.chat.response.module extract result')}
|
||||
value={activeModule?.extractResult}
|
||||
/>
|
||||
</>
|
||||
|
||||
{/* http */}
|
||||
<>
|
||||
{activeModule?.headers && (
|
||||
<Row
|
||||
label={'Headers'}
|
||||
value={`~~~json\n${JSON.stringify(activeModule?.headers, null, 2)}`}
|
||||
/>
|
||||
)}
|
||||
{activeModule?.params && (
|
||||
<Row
|
||||
label={'Params'}
|
||||
value={`~~~json\n${JSON.stringify(activeModule?.params, null, 2)}`}
|
||||
/>
|
||||
)}
|
||||
{activeModule?.body && (
|
||||
<Row label={'Body'} value={`~~~json\n${JSON.stringify(activeModule?.body, null, 2)}`} />
|
||||
)}
|
||||
{activeModule?.httpResult && (
|
||||
<Row
|
||||
label={t('core.chat.response.module http result')}
|
||||
value={`~~~json\n${JSON.stringify(activeModule?.httpResult, null, 2)}`}
|
||||
/>
|
||||
)}
|
||||
<Row label={'Headers'} value={activeModule?.headers} />
|
||||
<Row label={'Params'} value={activeModule?.params} />
|
||||
<Row label={'Body'} value={activeModule?.body} />
|
||||
<Row
|
||||
label={t('core.chat.response.module http result')}
|
||||
value={activeModule?.httpResult}
|
||||
/>
|
||||
</>
|
||||
|
||||
{/* plugin */}
|
||||
<>
|
||||
{activeModule?.pluginOutput && (
|
||||
<Row
|
||||
label={t('core.chat.response.plugin output')}
|
||||
value={`~~~json\n${JSON.stringify(activeModule?.pluginOutput, null, 2)}`}
|
||||
/>
|
||||
)}
|
||||
<Row label={t('core.chat.response.plugin output')} value={activeModule?.pluginOutput} />
|
||||
{activeModule?.pluginDetail && activeModule?.pluginDetail.length > 0 && (
|
||||
<Row
|
||||
label={t('core.chat.response.Plugin response detail')}
|
||||
@@ -310,6 +316,10 @@ export const ResponseBox = React.memo(function ResponseBox({
|
||||
rawDom={<ResponseBox response={activeModule.toolDetail} showDetail={showDetail} />}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* code */}
|
||||
<Row label={workflowT('response.Custom inputs')} value={activeModule?.customInputs} />
|
||||
<Row label={workflowT('response.Custom outputs')} value={activeModule?.customOutputs} />
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
|
@@ -58,7 +58,8 @@ const nodeTypes: Record<FlowNodeTypeEnum, any> = {
|
||||
),
|
||||
[FlowNodeTypeEnum.lafModule]: dynamic(() => import('./nodes/NodeLaf')),
|
||||
[FlowNodeTypeEnum.ifElseNode]: dynamic(() => import('./nodes/NodeIfElse')),
|
||||
[FlowNodeTypeEnum.variableUpdate]: dynamic(() => import('./nodes/NodeVariableUpdate'))
|
||||
[FlowNodeTypeEnum.variableUpdate]: dynamic(() => import('./nodes/NodeVariableUpdate')),
|
||||
[FlowNodeTypeEnum.code]: dynamic(() => import('./nodes/NodeCode'))
|
||||
};
|
||||
const edgeTypes = {
|
||||
[EDGE_TYPE]: ButtonEdge
|
||||
|
@@ -0,0 +1,107 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { NodeProps } from 'reactflow';
|
||||
import NodeCard from './render/NodeCard';
|
||||
import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
|
||||
import Container from '../components/Container';
|
||||
import RenderInput from './render/RenderInput';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io.d';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext } from '../../context';
|
||||
import IOTitle from '../components/IOTitle';
|
||||
import RenderToolInput from './render/RenderToolInput';
|
||||
import RenderOutput from './render/RenderOutput';
|
||||
import CodeEditor from '@fastgpt/web/components/common/Textarea/CodeEditor';
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { JS_TEMPLATE } from '@fastgpt/global/core/workflow/template/system/sandbox/constants';
|
||||
|
||||
const NodeCode = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
const { t } = useTranslation();
|
||||
const { workflowT } = useI18n();
|
||||
const { nodeId, inputs, outputs } = data;
|
||||
const splitToolInputs = useContextSelector(WorkflowContext, (ctx) => ctx.splitToolInputs);
|
||||
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||
const { toolInputs, commonInputs } = splitToolInputs(inputs, nodeId);
|
||||
const { ConfirmModal, openConfirm } = useConfirm({
|
||||
content: workflowT('code.Reset template confirm')
|
||||
});
|
||||
|
||||
const CustomComponent = useMemo(
|
||||
() => ({
|
||||
[NodeInputKeyEnum.code]: (item: FlowNodeInputItemType) => {
|
||||
return (
|
||||
<Box>
|
||||
<Flex mb={1} alignItems={'flex-end'}>
|
||||
<Box flex={'1'}>{workflowT('Code')}</Box>
|
||||
<Box
|
||||
cursor={'pointer'}
|
||||
color={'primary.500'}
|
||||
fontSize={'xs'}
|
||||
onClick={openConfirm(() => {
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: item.key,
|
||||
value: {
|
||||
...item,
|
||||
value: JS_TEMPLATE
|
||||
}
|
||||
});
|
||||
})}
|
||||
>
|
||||
{workflowT('code.Reset template')}
|
||||
</Box>
|
||||
</Flex>
|
||||
<CodeEditor
|
||||
bg={'white'}
|
||||
borderRadius={'sm'}
|
||||
value={item.value}
|
||||
onChange={(e) => {
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: item.key,
|
||||
value: {
|
||||
...item,
|
||||
value: e
|
||||
}
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}),
|
||||
[nodeId, onChangeNode, openConfirm, workflowT]
|
||||
);
|
||||
|
||||
return (
|
||||
<NodeCard minW={'400px'} selected={selected} {...data}>
|
||||
{toolInputs.length > 0 && (
|
||||
<>
|
||||
<Container>
|
||||
<IOTitle text={t('core.module.tool.Tool input')} />
|
||||
<RenderToolInput nodeId={nodeId} inputs={toolInputs} />
|
||||
</Container>
|
||||
</>
|
||||
)}
|
||||
<Container>
|
||||
<IOTitle text={t('common.Input')} />
|
||||
<RenderInput
|
||||
nodeId={nodeId}
|
||||
flowInputList={commonInputs}
|
||||
CustomComponent={CustomComponent}
|
||||
/>
|
||||
</Container>
|
||||
<Container>
|
||||
<IOTitle text={t('common.Output')} />
|
||||
<RenderOutput nodeId={nodeId} flowOutputList={outputs} />
|
||||
</Container>
|
||||
<ConfirmModal />
|
||||
</NodeCard>
|
||||
);
|
||||
};
|
||||
export default React.memo(NodeCode);
|
@@ -72,7 +72,6 @@ const AddInputParam = (props: RenderInputProps) => {
|
||||
leftIcon={<SmallAddIcon />}
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
mr={'-5px'}
|
||||
onClick={() => setEditField(item.dynamicParamDefaultValue ?? {})}
|
||||
>
|
||||
{t('common.Add New')}
|
||||
|
@@ -13,6 +13,7 @@ import { FlowValueTypeMap } from '@/web/core/workflow/constants/dataType';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext } from '@/components/core/workflow/context';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
|
||||
const RenderList: {
|
||||
types: `${FlowNodeOutputTypeEnum}`[];
|
||||
@@ -61,6 +62,7 @@ const RenderOutput = ({
|
||||
<Box position={'relative'} fontWeight={'medium'}>
|
||||
{t('core.workflow.Custom outputs')}
|
||||
</Box>
|
||||
<QuestionTip ml={1} label={addOutput.description} />
|
||||
<Box flex={'1 0 0'} />
|
||||
<Button
|
||||
variant={'whitePrimary'}
|
||||
|
@@ -148,7 +148,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
|
||||
if ((await targetCol.countDocuments()) > 1) {
|
||||
// 除了root
|
||||
console.log('team_members 中有数据,无法自动将 buffer.tts 迁移到 team_members,请手动操作');
|
||||
console.log('team_members 中有数据,无法自动将 team.tts 迁移到 team_members,请手动操作');
|
||||
} else {
|
||||
await sourceCol.rename('team_members', { dropTarget: true });
|
||||
console.log('success rename team.members -> team_members');
|
||||
|
Reference in New Issue
Block a user