v4.4.6 (#377)
This commit is contained in:
parent
c65a36d3ab
commit
98ce5103a0
@ -4,7 +4,7 @@ description: 'FastGPT 从旧版本升级到 V4.0 操作指南'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 1000
|
weight: 850
|
||||||
---
|
---
|
||||||
|
|
||||||
如果您是**从旧版本升级到 V4**,由于新版 MongoDB 表变更比较大,需要按照本文档的说明执行一些初始化脚本。
|
如果您是**从旧版本升级到 V4**,由于新版 MongoDB 表变更比较大,需要按照本文档的说明执行一些初始化脚本。
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: 'FastGPT 从旧版本升级到 V4.1 操作指南'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 999
|
weight: 849
|
||||||
---
|
---
|
||||||
|
|
||||||
如果您是**从旧版本升级到 V4.1**,由于新版重新设置了对话存储结构,需要初始化原来的存储内容。
|
如果您是**从旧版本升级到 V4.1**,由于新版重新设置了对话存储结构,需要初始化原来的存储内容。
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: 'FastGPT 从旧版本升级到 V4.2 操作指南'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 998
|
weight: 848
|
||||||
---
|
---
|
||||||
|
|
||||||
99.9%用户不影响,升级 4.2 主要是修改了配置文件中 QAModel 的格式。从原先的数组改成对象:
|
99.9%用户不影响,升级 4.2 主要是修改了配置文件中 QAModel 的格式。从原先的数组改成对象:
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: 'FastGPT 从旧版本升级到 V4.2.1 操作指南'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 997
|
weight: 847
|
||||||
---
|
---
|
||||||
|
|
||||||
私有部署,如果添加了配置文件,需要在配置文件中修改 `VectorModels` 字段。增加 defaultToken 和 maxToken,分别对应直接分段时的默认 token 数量和该模型支持的 token 上限(通常不建议超过 3000)
|
私有部署,如果添加了配置文件,需要在配置文件中修改 `VectorModels` 字段。增加 defaultToken 和 maxToken,分别对应直接分段时的默认 token 数量和该模型支持的 token 上限(通常不建议超过 3000)
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: 'FastGPT 从旧版本升级到 V4.3 操作指南'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 996
|
weight: 846
|
||||||
---
|
---
|
||||||
|
|
||||||
## 执行初始化 API
|
## 执行初始化 API
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: 'FastGPT 从旧版本升级到 V4.4 操作指南'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 995
|
weight: 845
|
||||||
---
|
---
|
||||||
|
|
||||||
## 执行初始化 API
|
## 执行初始化 API
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: 'FastGPT 从旧版本升级到 V4.4.1 操作指南'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 994
|
weight: 844
|
||||||
---
|
---
|
||||||
|
|
||||||
## 执行初始化 API
|
## 执行初始化 API
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: 'FastGPT 从旧版本升级到 V4.4.2 操作指南'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 993
|
weight: 843
|
||||||
---
|
---
|
||||||
|
|
||||||
## 执行初始化 API
|
## 执行初始化 API
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: 'FastGPT V4.4.5 更新(需执行升级脚本)'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 992
|
weight: 842
|
||||||
---
|
---
|
||||||
|
|
||||||
## 执行初始化 API
|
## 执行初始化 API
|
||||||
|
|||||||
14
docSite/content/docs/installation/upgrading/446.md
Normal file
14
docSite/content/docs/installation/upgrading/446.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
title: 'V4.4.6'
|
||||||
|
description: 'FastGPT V4.4.6 更新'
|
||||||
|
icon: 'upgrade'
|
||||||
|
draft: false
|
||||||
|
toc: true
|
||||||
|
weight: 841
|
||||||
|
---
|
||||||
|
|
||||||
|
## 功能介绍
|
||||||
|
|
||||||
|
1. 高级编排新增模块 - 应用调用,可调用其他应用。
|
||||||
|
2. 新增 - 必要连接校验
|
||||||
|
3. 修复 - 下一步指引在免登录中身份问题。
|
||||||
57
packages/core/ai/functions/createQuestionGuide.ts
Normal file
57
packages/core/ai/functions/createQuestionGuide.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { ChatCompletionRequestMessage } from '../type';
|
||||||
|
import { getAIChatApi } from '../config';
|
||||||
|
|
||||||
|
export const Prompt_QuestionGuide = `我不太清楚问你什么问题,请帮我生成 3 个问题,引导我继续提问。问题的长度应小于20个字符,按 JSON 格式返回: ["问题1", "问题2", "问题3"]`;
|
||||||
|
|
||||||
|
export async function createQuestionGuide({
|
||||||
|
messages,
|
||||||
|
model
|
||||||
|
}: {
|
||||||
|
messages: ChatCompletionRequestMessage[];
|
||||||
|
model: string;
|
||||||
|
}) {
|
||||||
|
const chatAPI = getAIChatApi();
|
||||||
|
const { data } = await chatAPI.createChatCompletion({
|
||||||
|
model: model,
|
||||||
|
temperature: 0,
|
||||||
|
max_tokens: 200,
|
||||||
|
messages: [
|
||||||
|
...messages,
|
||||||
|
{
|
||||||
|
role: 'user',
|
||||||
|
content: Prompt_QuestionGuide
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stream: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const answer = data.choices?.[0].message?.content || '';
|
||||||
|
const totalTokens = data.usage?.total_tokens || 0;
|
||||||
|
|
||||||
|
const start = answer.indexOf('[');
|
||||||
|
const end = answer.lastIndexOf(']');
|
||||||
|
|
||||||
|
if (start === -1 || end === -1) {
|
||||||
|
return {
|
||||||
|
result: [],
|
||||||
|
tokens: totalTokens
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsonStr = answer
|
||||||
|
.substring(start, end + 1)
|
||||||
|
.replace(/(\\n|\\)/g, '')
|
||||||
|
.replace(/ /g, '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
result: JSON.parse(jsonStr),
|
||||||
|
tokens: totalTokens
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
result: [],
|
||||||
|
tokens: totalTokens
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
@ -1,4 +1,4 @@
|
|||||||
lockfileVersion: '6.0'
|
lockfileVersion: '6.1'
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"version": "4.4.5",
|
"version": "4.4.6",
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
### Fast GPT V4.4.5
|
### Fast GPT V4.4.6
|
||||||
|
|
||||||
1. 新增 - 下一步指引选项,可以通过模型生成 3 个预测问题。
|
1. 高级编排新增模块 - 应用调用
|
||||||
2. 新增 - 分享链接 hook 身份校验。
|
2. 新增 - 必要连接校验
|
||||||
3. 新增 - Api Key 使用。增加别名、额度限制和过期时间。自带 appId,无需额外连接。
|
3. 新增 - 下一步指引选项,可以通过模型生成 3 个预测问题。
|
||||||
4. 去除 - 限定词。目前旧应用仍生效,9/25 后全面去除,请及时替换。
|
4. 新增 - 分享链接 hook 身份校验。
|
||||||
5. 新增 - 引用模板/引用提示词设置,可以 DIY 引用内容的格式,从而更好的适配场景。[参考文档](https://doc.fastgpt.run/docs/use-cases/prompt/)
|
5. [使用文档](https://doc.fastgpt.run/docs/intro/)
|
||||||
6. [使用文档](https://doc.fastgpt.run/docs/intro/)
|
6. [点击查看高级编排介绍文档](https://doc.fastgpt.run/docs/workflow)
|
||||||
7. [点击查看高级编排介绍文档](https://doc.fastgpt.run/docs/workflow)
|
7. [点击查看商业版](https://doc.fastgpt.run/docs/commercial/)
|
||||||
8. [点击查看商业版](https://doc.fastgpt.run/docs/commercial/)
|
|
||||||
|
|||||||
BIN
projects/app/public/imgs/module/app.png
Normal file
BIN
projects/app/public/imgs/module/app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
@ -96,6 +96,7 @@
|
|||||||
"module question": "Question",
|
"module question": "Question",
|
||||||
"module quoteList": "Quotes",
|
"module quoteList": "Quotes",
|
||||||
"module runningTime": "Time",
|
"module runningTime": "Time",
|
||||||
|
"module search response": "Search Result",
|
||||||
"module similarity": "Similarity",
|
"module similarity": "Similarity",
|
||||||
"module temperature": "Temperature",
|
"module temperature": "Temperature",
|
||||||
"module time": "Running Time",
|
"module time": "Running Time",
|
||||||
|
|||||||
@ -96,6 +96,7 @@
|
|||||||
"module question": "问题",
|
"module question": "问题",
|
||||||
"module quoteList": "引用内容",
|
"module quoteList": "引用内容",
|
||||||
"module runningTime": "运行时长",
|
"module runningTime": "运行时长",
|
||||||
|
"module search response": "搜索结果",
|
||||||
"module similarity": "相似度",
|
"module similarity": "相似度",
|
||||||
"module temperature": "温度",
|
"module temperature": "温度",
|
||||||
"module time": "运行时长",
|
"module time": "运行时长",
|
||||||
|
|||||||
3
projects/app/src/api/core/ai/agent/type.d.ts
vendored
3
projects/app/src/api/core/ai/agent/type.d.ts
vendored
@ -1,5 +1,6 @@
|
|||||||
import { ChatCompletionRequestMessage } from '@fastgpt/core/aiApi/type';
|
import { ChatCompletionRequestMessage } from '@fastgpt/core/ai/type';
|
||||||
|
|
||||||
export type CreateQuestionGuideProps = {
|
export type CreateQuestionGuideProps = {
|
||||||
messages: ChatCompletionRequestMessage[];
|
messages: ChatCompletionRequestMessage[];
|
||||||
|
shareId?: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,15 +12,7 @@ const QuoteModal = dynamic(() => import('./QuoteModal'), { ssr: false });
|
|||||||
const ContextModal = dynamic(() => import('./ContextModal'), { ssr: false });
|
const ContextModal = dynamic(() => import('./ContextModal'), { ssr: false });
|
||||||
const WholeResponseModal = dynamic(() => import('./WholeResponseModal'), { ssr: false });
|
const WholeResponseModal = dynamic(() => import('./WholeResponseModal'), { ssr: false });
|
||||||
|
|
||||||
const ResponseTags = ({
|
const ResponseTags = ({ responseData = [] }: { responseData?: ChatHistoryItemResType[] }) => {
|
||||||
chatId,
|
|
||||||
contentId,
|
|
||||||
responseData = []
|
|
||||||
}: {
|
|
||||||
chatId?: string;
|
|
||||||
contentId?: string;
|
|
||||||
responseData?: ChatHistoryItemResType[];
|
|
||||||
}) => {
|
|
||||||
const { isPc } = useGlobalStore();
|
const { isPc } = useGlobalStore();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [quoteModalData, setQuoteModalData] = useState<QuoteItemType[]>();
|
const [quoteModalData, setQuoteModalData] = useState<QuoteItemType[]>();
|
||||||
@ -41,9 +33,12 @@ const ResponseTags = ({
|
|||||||
return {
|
return {
|
||||||
chatAccount: responseData.filter((item) => item.moduleType === FlowModuleTypeEnum.chatNode)
|
chatAccount: responseData.filter((item) => item.moduleType === FlowModuleTypeEnum.chatNode)
|
||||||
.length,
|
.length,
|
||||||
quoteList: chatData?.quoteList,
|
quoteList: responseData
|
||||||
|
.filter((item) => item.moduleType === FlowModuleTypeEnum.chatNode)
|
||||||
|
.map((item) => item.quoteList)
|
||||||
|
.flat(),
|
||||||
historyPreview: chatData?.historyPreview,
|
historyPreview: chatData?.historyPreview,
|
||||||
runningTime: responseData.reduce((sum, item) => sum + (item.runningTime || 0), 0).toFixed(2)
|
runningTime: +responseData.reduce((sum, item) => sum + (item.runningTime || 0), 0).toFixed(2)
|
||||||
};
|
};
|
||||||
}, [responseData]);
|
}, [responseData]);
|
||||||
|
|
||||||
@ -56,20 +51,20 @@ const ResponseTags = ({
|
|||||||
|
|
||||||
return responseData.length === 0 ? null : (
|
return responseData.length === 0 ? null : (
|
||||||
<Flex alignItems={'center'} mt={2} flexWrap={'wrap'}>
|
<Flex alignItems={'center'} mt={2} flexWrap={'wrap'}>
|
||||||
|
{quoteList.length > 0 && (
|
||||||
|
<MyTooltip label="查看引用">
|
||||||
|
<Tag
|
||||||
|
colorSchema="blue"
|
||||||
|
cursor={'pointer'}
|
||||||
|
{...TagStyles}
|
||||||
|
onClick={() => setQuoteModalData(quoteList)}
|
||||||
|
>
|
||||||
|
{quoteList.length}条引用
|
||||||
|
</Tag>
|
||||||
|
</MyTooltip>
|
||||||
|
)}
|
||||||
{chatAccount === 1 && (
|
{chatAccount === 1 && (
|
||||||
<>
|
<>
|
||||||
{quoteList.length > 0 && (
|
|
||||||
<MyTooltip label="查看引用">
|
|
||||||
<Tag
|
|
||||||
colorSchema="blue"
|
|
||||||
cursor={'pointer'}
|
|
||||||
{...TagStyles}
|
|
||||||
onClick={() => setQuoteModalData(quoteList)}
|
|
||||||
>
|
|
||||||
{quoteList.length}条引用
|
|
||||||
</Tag>
|
|
||||||
</MyTooltip>
|
|
||||||
)}
|
|
||||||
{historyPreview.length > 0 && (
|
{historyPreview.length > 0 && (
|
||||||
<MyTooltip label={'点击查看完整对话记录'}>
|
<MyTooltip label={'点击查看完整对话记录'}>
|
||||||
<Tag
|
<Tag
|
||||||
@ -120,4 +115,4 @@ const ResponseTags = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ResponseTags;
|
export default React.memo(ResponseTags);
|
||||||
|
|||||||
@ -34,7 +34,7 @@ import { feConfigs } from '@/store/static';
|
|||||||
import { event } from '@/utils/plugin/eventbus';
|
import { event } from '@/utils/plugin/eventbus';
|
||||||
import { adaptChat2GptMessages } from '@/utils/common/adapt/message';
|
import { adaptChat2GptMessages } from '@/utils/common/adapt/message';
|
||||||
import { useMarkdown } from '@/hooks/useMarkdown';
|
import { useMarkdown } from '@/hooks/useMarkdown';
|
||||||
import { AppModuleItemType, VariableItemType } from '@/types/app';
|
import { AppModuleItemType } from '@/types/app';
|
||||||
import { VariableInputEnum } from '@/constants/app';
|
import { VariableInputEnum } from '@/constants/app';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import type { MessageItemType } from '@/types/core/chat/type';
|
import type { MessageItemType } from '@/types/core/chat/type';
|
||||||
@ -81,7 +81,7 @@ export type StartChatFnProps = {
|
|||||||
export type ComponentRef = {
|
export type ComponentRef = {
|
||||||
getChatHistory: () => ChatSiteItemType[];
|
getChatHistory: () => ChatSiteItemType[];
|
||||||
resetVariables: (data?: Record<string, any>) => void;
|
resetVariables: (data?: Record<string, any>) => void;
|
||||||
resetHistory: (chatId: ChatSiteItemType[]) => void;
|
resetHistory: (history: ChatSiteItemType[]) => void;
|
||||||
scrollToBottom: (behavior?: 'smooth' | 'auto') => void;
|
scrollToBottom: (behavior?: 'smooth' | 'auto') => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -96,7 +96,6 @@ type Props = {
|
|||||||
showMarkIcon?: boolean; // admin mark dataset
|
showMarkIcon?: boolean; // admin mark dataset
|
||||||
showVoiceIcon?: boolean;
|
showVoiceIcon?: boolean;
|
||||||
showEmptyIntro?: boolean;
|
showEmptyIntro?: boolean;
|
||||||
chatId?: string;
|
|
||||||
appAvatar?: string;
|
appAvatar?: string;
|
||||||
userAvatar?: string;
|
userAvatar?: string;
|
||||||
userGuideModule?: AppModuleItemType;
|
userGuideModule?: AppModuleItemType;
|
||||||
@ -116,7 +115,6 @@ const ChatBox = (
|
|||||||
showMarkIcon = false,
|
showMarkIcon = false,
|
||||||
showVoiceIcon = true,
|
showVoiceIcon = true,
|
||||||
showEmptyIntro = false,
|
showEmptyIntro = false,
|
||||||
chatId,
|
|
||||||
appAvatar,
|
appAvatar,
|
||||||
userAvatar,
|
userAvatar,
|
||||||
userGuideModule,
|
userGuideModule,
|
||||||
@ -265,7 +263,8 @@ const ChatBox = (
|
|||||||
|
|
||||||
const result = await postQuestionGuide(
|
const result = await postQuestionGuide(
|
||||||
{
|
{
|
||||||
messages: adaptChat2GptMessages({ messages: history, reserveId: false }).slice(-6)
|
messages: adaptChat2GptMessages({ messages: history, reserveId: false }).slice(-6),
|
||||||
|
shareId: router.query.shareId as string
|
||||||
},
|
},
|
||||||
abortSignal
|
abortSignal
|
||||||
);
|
);
|
||||||
@ -277,7 +276,7 @@ const ChatBox = (
|
|||||||
}
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
},
|
},
|
||||||
[questionGuide, scrollToBottom]
|
[questionGuide, scrollToBottom, router.query.shareId]
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -743,11 +742,7 @@ const ChatBox = (
|
|||||||
source={item.value}
|
source={item.value}
|
||||||
isChatting={index === chatHistory.length - 1 && isChatting}
|
isChatting={index === chatHistory.length - 1 && isChatting}
|
||||||
/>
|
/>
|
||||||
<ResponseTags
|
<ResponseTags responseData={item.responseData} />
|
||||||
chatId={chatId}
|
|
||||||
contentId={item.dataId}
|
|
||||||
responseData={item.responseData}
|
|
||||||
/>
|
|
||||||
{/* question guide */}
|
{/* question guide */}
|
||||||
{index === chatHistory.length - 1 &&
|
{index === chatHistory.length - 1 &&
|
||||||
!isChatting &&
|
!isChatting &&
|
||||||
|
|||||||
@ -20,19 +20,17 @@ function MyLink(e: any) {
|
|||||||
{text}
|
{text}
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
<Box as={'ul'} mt={'0 !important'}>
|
<Box as={'li'} mb={1}>
|
||||||
<Box as={'li'} mb={1}>
|
<Box
|
||||||
<Box
|
as={'span'}
|
||||||
as={'span'}
|
color={'blue.600'}
|
||||||
color={'blue.600'}
|
textDecoration={'underline'}
|
||||||
textDecoration={'underline'}
|
cursor={'pointer'}
|
||||||
cursor={'pointer'}
|
onClick={() => {
|
||||||
onClick={() => {
|
event.emit('guideClick', { text });
|
||||||
event.emit('guideClick', { text });
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{text}
|
||||||
{text}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@ -40,9 +38,10 @@ function MyLink(e: any) {
|
|||||||
|
|
||||||
const Guide = ({ text }: { text: string }) => {
|
const Guide = ({ text }: { text: string }) => {
|
||||||
const formatText = useMemo(
|
const formatText = useMemo(
|
||||||
() => text.replace(/\[(.*?)\]($|\n)/g, '[$1]()\n').replace(/\\n/g, '\n '),
|
() => text.replace(/\[(.*?)\]($|\n)/g, '[$1]()').replace(/\\n/g, '\n '),
|
||||||
[text]
|
[text]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
className={`markdown ${styles.markdown}`}
|
className={`markdown ${styles.markdown}`}
|
||||||
|
|||||||
@ -15,7 +15,8 @@ export enum ChatRoleEnum {
|
|||||||
|
|
||||||
export enum TaskResponseKeyEnum {
|
export enum TaskResponseKeyEnum {
|
||||||
'answerText' = 'answerText', // answer module text key
|
'answerText' = 'answerText', // answer module text key
|
||||||
'responseData' = 'responseData'
|
'responseData' = 'responseData',
|
||||||
|
'history' = 'history'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ChatRoleMap = {
|
export const ChatRoleMap = {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export const ChatModelSystemTip =
|
|||||||
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}';
|
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}';
|
||||||
export const ChatModelLimitTip =
|
export const ChatModelLimitTip =
|
||||||
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。不建议内容太长,会影响上下文,可使用变量,例如 {{language}}。可在文档中找到对应的限定例子';
|
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。不建议内容太长,会影响上下文,可使用变量,例如 {{language}}。可在文档中找到对应的限定例子';
|
||||||
export const userGuideTip = '可以添加特殊的对话前后引导模块,更好的让用户进行对话';
|
export const userGuideTip = '可以在对话前设置引导语,设置全局变量,设置下一步指引';
|
||||||
export const welcomeTextTip =
|
export const welcomeTextTip =
|
||||||
'每次对话开始前,发送一个初始内容。支持标准 Markdown 语法,可使用的额外标记:\n[快捷按键]: 用户点击后可以直接发送该问题';
|
'每次对话开始前,发送一个初始内容。支持标准 Markdown 语法,可使用的额外标记:\n[快捷按键]: 用户点击后可以直接发送该问题';
|
||||||
export const variableTip =
|
export const variableTip =
|
||||||
@ -203,6 +203,14 @@ export const ChatModule: FlowModuleTemplateType = {
|
|||||||
Input_Template_UserChatInput
|
Input_Template_UserChatInput
|
||||||
],
|
],
|
||||||
outputs: [
|
outputs: [
|
||||||
|
{
|
||||||
|
key: TaskResponseKeyEnum.history,
|
||||||
|
label: '新的上下文',
|
||||||
|
description: '将本次回复内容拼接上历史记录,作为新的上下文返回',
|
||||||
|
valueType: FlowValueTypeEnum.chatHistory,
|
||||||
|
type: FlowOutputItemTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: TaskResponseKeyEnum.answerText,
|
key: TaskResponseKeyEnum.answerText,
|
||||||
label: '模型回复',
|
label: '模型回复',
|
||||||
@ -483,6 +491,51 @@ export const EmptyModule: FlowModuleTemplateType = {
|
|||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
};
|
};
|
||||||
|
export const AppModule: FlowModuleTemplateType = {
|
||||||
|
flowType: FlowModuleTypeEnum.app,
|
||||||
|
logo: '/imgs/module/app.png',
|
||||||
|
name: '应用调用(测试版)',
|
||||||
|
intro: '可以选择一个其他应用进行调用',
|
||||||
|
description: '可以选择一个其他应用进行调用',
|
||||||
|
showStatus: true,
|
||||||
|
inputs: [
|
||||||
|
Input_Template_TFSwitch,
|
||||||
|
{
|
||||||
|
key: 'app',
|
||||||
|
type: FlowInputItemTypeEnum.selectApp,
|
||||||
|
label: '选择一个应用',
|
||||||
|
description: '选择一个其他应用进行调用',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
Input_Template_History,
|
||||||
|
Input_Template_UserChatInput
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
key: TaskResponseKeyEnum.history,
|
||||||
|
label: '新的上下文',
|
||||||
|
description: '将该应用回复内容拼接到历史记录中,作为新的上下文返回',
|
||||||
|
valueType: FlowValueTypeEnum.chatHistory,
|
||||||
|
type: FlowOutputItemTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: TaskResponseKeyEnum.answerText,
|
||||||
|
label: '模型回复',
|
||||||
|
description: '将在应用完全结束后触发',
|
||||||
|
valueType: FlowValueTypeEnum.string,
|
||||||
|
type: FlowOutputItemTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'finish',
|
||||||
|
label: '请求结束',
|
||||||
|
valueType: FlowValueTypeEnum.boolean,
|
||||||
|
type: FlowOutputItemTypeEnum.source,
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
export const ModuleTemplates = [
|
export const ModuleTemplates = [
|
||||||
{
|
{
|
||||||
@ -498,11 +551,11 @@ export const ModuleTemplates = [
|
|||||||
list: [ChatModule, AnswerModule]
|
list: [ChatModule, AnswerModule]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '知识库模块',
|
label: '核心调用',
|
||||||
list: [KBSearchModule]
|
list: [KBSearchModule, AppModule]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Agent',
|
label: '函数模块',
|
||||||
list: [ClassifyQuestionModule, ContextExtractModule, HttpModule]
|
list: [ClassifyQuestionModule, ContextExtractModule, HttpModule]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -517,7 +570,8 @@ export const ModuleTemplatesFlat = [
|
|||||||
ClassifyQuestionModule,
|
ClassifyQuestionModule,
|
||||||
ContextExtractModule,
|
ContextExtractModule,
|
||||||
HttpModule,
|
HttpModule,
|
||||||
EmptyModule
|
EmptyModule,
|
||||||
|
AppModule
|
||||||
];
|
];
|
||||||
|
|
||||||
// template
|
// template
|
||||||
@ -528,6 +582,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
name: '简单的对话',
|
name: '简单的对话',
|
||||||
intro: '一个极其简单的 AI 对话应用',
|
intro: '一个极其简单的 AI 对话应用',
|
||||||
modules: [
|
modules: [
|
||||||
|
{
|
||||||
|
moduleId: 'userGuide',
|
||||||
|
name: '用户引导',
|
||||||
|
flowType: 'userGuide',
|
||||||
|
position: {
|
||||||
|
x: 454.98510354678695,
|
||||||
|
y: 721.4016845336229
|
||||||
|
},
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
key: 'welcomeText',
|
||||||
|
type: 'input',
|
||||||
|
label: '开场白',
|
||||||
|
value: '',
|
||||||
|
connected: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
moduleId: 'userChatInput',
|
moduleId: 'userChatInput',
|
||||||
name: '用户问题(对话入口)',
|
name: '用户问题(对话入口)',
|
||||||
@ -1382,10 +1455,6 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
moduleId: 'remuj3',
|
moduleId: 'remuj3',
|
||||||
key: 'userChatInput'
|
key: 'userChatInput'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
moduleId: 'nlfwkc',
|
|
||||||
key: 'userChatInput'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
moduleId: 'fljhzy',
|
moduleId: 'fljhzy',
|
||||||
key: 'userChatInput'
|
key: 'userChatInput'
|
||||||
@ -1399,8 +1468,8 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
name: '聊天记录',
|
name: '聊天记录',
|
||||||
flowType: 'historyNode',
|
flowType: 'historyNode',
|
||||||
position: {
|
position: {
|
||||||
x: 194.99102398958047,
|
x: 1770.497690708367,
|
||||||
y: 1801.3545999721096
|
y: 1820.2355054321215
|
||||||
},
|
},
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
@ -1444,16 +1513,23 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
y: 1077.557793775116
|
y: 1077.557793775116
|
||||||
},
|
},
|
||||||
inputs: [
|
inputs: [
|
||||||
|
{
|
||||||
|
key: 'switch',
|
||||||
|
type: 'target',
|
||||||
|
label: '触发器',
|
||||||
|
valueType: 'any',
|
||||||
|
connected: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'systemPrompt',
|
key: 'systemPrompt',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
valueType: 'string',
|
valueType: 'string',
|
||||||
|
value:
|
||||||
|
'laf 是云开发平台,可以快速的开发应用\nlaf 是一个开源的 BaaS 开发平台(Backend as a Service)\nlaf 是一个开箱即用的 serverless 开发平台\nlaf 是一个集「函数计算」、「数据库」、「对象存储」等于一身的一站式开发平台\nlaf 可以是开源版的腾讯云开发、开源版的 Google Firebase、开源版的 UniCloud',
|
||||||
label: '系统提示词',
|
label: '系统提示词',
|
||||||
description:
|
description:
|
||||||
'你可以添加一些特定内容的介绍,从而更好的识别用户的问题类型。这个内容通常是给模型介绍一个它不知道的内容。',
|
'你可以添加一些特定内容的介绍,从而更好的识别用户的问题类型。这个内容通常是给模型介绍一个它不知道的内容。',
|
||||||
placeholder: '例如: \n1. Laf 是一个云函数开发平台……\n2. Sealos 是一个集群操作系统',
|
placeholder: '例如: \n1. Laf 是一个云函数开发平台……\n2. Sealos 是一个集群操作系统',
|
||||||
value:
|
|
||||||
'laf 是云开发平台,可以快速的开发应用\nlaf 是一个开源的 BaaS 开发平台(Backend as a Service)\nlaf 是一个开箱即用的 serverless 开发平台\nlaf 是一个集「函数计算」、「数据库」、「对象存储」等于一身的一站式开发平台\nlaf 可以是开源版的腾讯云开发、开源版的 Google Firebase、开源版的 UniCloud',
|
|
||||||
connected: true
|
connected: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1561,16 +1637,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'text',
|
key: 'text',
|
||||||
value: '你好,我是 laf 助手,有什么可以帮助你的?',
|
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
valueType: 'string',
|
valueType: 'string',
|
||||||
|
value: '你好,我是 laf 助手,有什么可以帮助你的?',
|
||||||
label: '回复的内容',
|
label: '回复的内容',
|
||||||
description:
|
description:
|
||||||
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
|
'可以使用 \\n 来实现连续换行。\n\n可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
|
||||||
connected: true
|
connected: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
outputs: []
|
outputs: [
|
||||||
|
{
|
||||||
|
key: 'finish',
|
||||||
|
label: '回复结束',
|
||||||
|
description: '回复完成后触发',
|
||||||
|
valueType: 'boolean',
|
||||||
|
type: 'source',
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleId: 'iejcou',
|
moduleId: 'iejcou',
|
||||||
@ -1590,16 +1675,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'text',
|
key: 'text',
|
||||||
value: '你好,我仅能回答 laf 相关问题,请问你有什么问题么?',
|
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
valueType: 'string',
|
valueType: 'string',
|
||||||
|
value: '你好,我仅能回答 laf 相关问题,请问你有什么问题么?',
|
||||||
label: '回复的内容',
|
label: '回复的内容',
|
||||||
description:
|
description:
|
||||||
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
|
'可以使用 \\n 来实现连续换行。\n\n可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
|
||||||
connected: true
|
connected: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
outputs: []
|
outputs: [
|
||||||
|
{
|
||||||
|
key: 'finish',
|
||||||
|
label: '回复结束',
|
||||||
|
description: '回复完成后触发',
|
||||||
|
valueType: 'boolean',
|
||||||
|
type: 'source',
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleId: 'nlfwkc',
|
moduleId: 'nlfwkc',
|
||||||
@ -1607,7 +1701,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
flowType: 'chatNode',
|
flowType: 'chatNode',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
position: {
|
position: {
|
||||||
x: 1821.979893659983,
|
x: 2260.436476009152,
|
||||||
y: 1104.6583548423682
|
y: 1104.6583548423682
|
||||||
},
|
},
|
||||||
inputs: [
|
inputs: [
|
||||||
@ -1616,7 +1710,48 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
type: 'custom',
|
type: 'custom',
|
||||||
label: '对话模型',
|
label: '对话模型',
|
||||||
value: 'gpt-3.5-turbo-16k',
|
value: 'gpt-3.5-turbo-16k',
|
||||||
list: [],
|
list: [
|
||||||
|
{
|
||||||
|
label: 'FastAI-4k',
|
||||||
|
value: 'gpt-3.5-turbo'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'FastAI-instruct',
|
||||||
|
value: 'gpt-3.5-turbo-instruct'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'FastAI-16k',
|
||||||
|
value: 'gpt-3.5-turbo-16k'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'FastAI-Plus-8k',
|
||||||
|
value: 'gpt-4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'FastAI-Plus-32k',
|
||||||
|
value: 'gpt-4-32k'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '百川2-13B(测试)',
|
||||||
|
value: 'baichuan2-13b'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '文心一言(QPS 5)',
|
||||||
|
value: 'ERNIE-Bot'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '星火2.0(QPS 2)',
|
||||||
|
value: 'SparkDesk'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'chatglm_pro(QPS 5)',
|
||||||
|
value: 'chatglm_pro'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '通义千问(QPS 5)',
|
||||||
|
value: 'qwen-v1'
|
||||||
|
}
|
||||||
|
],
|
||||||
connected: true
|
connected: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1663,6 +1798,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
key: 'systemPrompt',
|
key: 'systemPrompt',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
label: '系统提示词',
|
label: '系统提示词',
|
||||||
|
max: 300,
|
||||||
valueType: 'string',
|
valueType: 'string',
|
||||||
description:
|
description:
|
||||||
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
|
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
|
||||||
@ -1671,6 +1807,22 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
value: '知识库是关于 laf 的内容。',
|
value: '知识库是关于 laf 的内容。',
|
||||||
connected: true
|
connected: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'quoteTemplate',
|
||||||
|
type: 'hidden',
|
||||||
|
label: '引用内容模板',
|
||||||
|
valueType: 'string',
|
||||||
|
value: '',
|
||||||
|
connected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'quotePrompt',
|
||||||
|
type: 'hidden',
|
||||||
|
label: '引用内容提示词',
|
||||||
|
valueType: 'string',
|
||||||
|
value: '',
|
||||||
|
connected: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'switch',
|
key: 'switch',
|
||||||
type: 'target',
|
type: 'target',
|
||||||
@ -1680,8 +1832,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'quoteQA',
|
key: 'quoteQA',
|
||||||
type: 'target',
|
type: 'custom',
|
||||||
label: '引用内容',
|
label: '引用内容',
|
||||||
|
description: "对象数组格式,结构:\n [{q:'问题',a:'回答'}]",
|
||||||
valueType: 'kb_quote',
|
valueType: 'kb_quote',
|
||||||
connected: true
|
connected: true
|
||||||
},
|
},
|
||||||
@ -1705,8 +1858,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
{
|
{
|
||||||
key: 'answerText',
|
key: 'answerText',
|
||||||
label: '模型回复',
|
label: '模型回复',
|
||||||
description: '直接响应,无需配置',
|
description: '将在 stream 回复完毕后触发',
|
||||||
type: 'hidden',
|
valueType: 'string',
|
||||||
|
type: 'source',
|
||||||
targets: []
|
targets: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1716,6 +1870,14 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
valueType: 'boolean',
|
valueType: 'boolean',
|
||||||
type: 'source',
|
type: 'source',
|
||||||
targets: []
|
targets: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'history',
|
||||||
|
label: '新的上下文',
|
||||||
|
description: '将本次回复内容拼接上历史记录,作为新的上下文返回',
|
||||||
|
valueType: 'chat_history',
|
||||||
|
type: 'source',
|
||||||
|
targets: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -1725,7 +1887,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
flowType: 'historyNode',
|
flowType: 'historyNode',
|
||||||
position: {
|
position: {
|
||||||
x: 193.3803955457983,
|
x: 193.3803955457983,
|
||||||
y: 1116.251200765746
|
y: 1316.251200765746
|
||||||
},
|
},
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
@ -1770,11 +1932,11 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
},
|
},
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
|
key: 'kbList',
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
label: '关联的知识库',
|
label: '关联的知识库',
|
||||||
list: [],
|
|
||||||
key: 'kbList',
|
|
||||||
value: [],
|
value: [],
|
||||||
|
list: [],
|
||||||
connected: true
|
connected: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1886,11 +2048,24 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'welcomeText',
|
key: 'welcomeText',
|
||||||
type: 'input',
|
type: 'hidden',
|
||||||
label: '开场白',
|
label: '开场白',
|
||||||
value:
|
value:
|
||||||
'你好,我是 laf 助手,有什么可以帮助你的?\n[laf 是什么?有什么用?]\n[laf 在线体验地址]\n[官网地址是多少]',
|
'你好,我是 laf 助手,有什么可以帮助你的?\n[laf 是什么?有什么用?]\n[laf 在线体验地址]\n[官网地址是多少]',
|
||||||
connected: true
|
connected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'variables',
|
||||||
|
type: 'hidden',
|
||||||
|
label: '对话框变量',
|
||||||
|
value: [],
|
||||||
|
connected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'questionGuide',
|
||||||
|
type: 'switch',
|
||||||
|
label: '问题引导',
|
||||||
|
connected: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
outputs: []
|
outputs: []
|
||||||
@ -1900,8 +2075,8 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
name: '指定回复',
|
name: '指定回复',
|
||||||
flowType: 'answerNode',
|
flowType: 'answerNode',
|
||||||
position: {
|
position: {
|
||||||
x: 1828.4596416688908,
|
x: 2262.720467249169,
|
||||||
y: 765.3628156185887
|
y: 750.6776669274682
|
||||||
},
|
},
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
@ -1913,16 +2088,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'text',
|
key: 'text',
|
||||||
value: '对不起,我找不到你的问题,请更加详细的描述你的问题。',
|
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
valueType: 'string',
|
valueType: 'string',
|
||||||
|
value: '对不起,我找不到你的问题,请更加详细的描述你的问题。',
|
||||||
label: '回复的内容',
|
label: '回复的内容',
|
||||||
description:
|
description:
|
||||||
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
|
'可以使用 \\n 来实现连续换行。\n\n可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
|
||||||
connected: true
|
connected: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
outputs: []
|
outputs: [
|
||||||
|
{
|
||||||
|
key: 'finish',
|
||||||
|
label: '回复结束',
|
||||||
|
description: '回复完成后触发',
|
||||||
|
valueType: 'boolean',
|
||||||
|
type: 'source',
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleId: '5v78ap',
|
moduleId: '5v78ap',
|
||||||
@ -1942,16 +2126,56 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'text',
|
key: 'text',
|
||||||
value: '这是一个商务问题',
|
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
valueType: 'string',
|
valueType: 'string',
|
||||||
|
value: '这是一个商务问题',
|
||||||
label: '回复的内容',
|
label: '回复的内容',
|
||||||
description:
|
description:
|
||||||
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
|
'可以使用 \\n 来实现连续换行。\n\n可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
|
||||||
connected: true
|
connected: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
outputs: []
|
outputs: [
|
||||||
|
{
|
||||||
|
key: 'finish',
|
||||||
|
label: '回复结束',
|
||||||
|
description: '回复完成后触发',
|
||||||
|
valueType: 'boolean',
|
||||||
|
type: 'source',
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleId: '9act94',
|
||||||
|
name: '用户问题(对话入口)',
|
||||||
|
flowType: 'questionInput',
|
||||||
|
position: {
|
||||||
|
x: 1827.2213090948171,
|
||||||
|
y: 2132.138812501788
|
||||||
|
},
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
key: 'userChatInput',
|
||||||
|
type: 'systemInput',
|
||||||
|
label: '用户问题',
|
||||||
|
connected: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
key: 'userChatInput',
|
||||||
|
label: '用户问题',
|
||||||
|
type: 'source',
|
||||||
|
valueType: 'string',
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
moduleId: 'nlfwkc',
|
||||||
|
key: 'userChatInput'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,8 @@ export enum FlowInputItemTypeEnum {
|
|||||||
target = 'target',
|
target = 'target',
|
||||||
none = 'none',
|
none = 'none',
|
||||||
switch = 'switch',
|
switch = 'switch',
|
||||||
hidden = 'hidden'
|
hidden = 'hidden',
|
||||||
|
selectApp = 'selectApp'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum FlowOutputItemTypeEnum {
|
export enum FlowOutputItemTypeEnum {
|
||||||
@ -33,7 +34,8 @@ export enum FlowModuleTypeEnum {
|
|||||||
answerNode = 'answerNode',
|
answerNode = 'answerNode',
|
||||||
classifyQuestion = 'classifyQuestion',
|
classifyQuestion = 'classifyQuestion',
|
||||||
contentExtract = 'contentExtract',
|
contentExtract = 'contentExtract',
|
||||||
httpRequest = 'httpRequest'
|
httpRequest = 'httpRequest',
|
||||||
|
app = 'app'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SpecialInputKeyEnum {
|
export enum SpecialInputKeyEnum {
|
||||||
|
|||||||
@ -3,71 +3,39 @@ import { jsonRes } from '@/service/response';
|
|||||||
import { connectToDatabase } from '@/service/mongo';
|
import { connectToDatabase } from '@/service/mongo';
|
||||||
import { authUser } from '@/service/utils/auth';
|
import { authUser } from '@/service/utils/auth';
|
||||||
import { CreateQuestionGuideProps } from '@/api/core/ai/agent/type';
|
import { CreateQuestionGuideProps } from '@/api/core/ai/agent/type';
|
||||||
import { getAIChatApi } from '@fastgpt/core/aiApi/config';
|
|
||||||
import { Prompt_QuestionGuide } from '@/prompts/core/agent';
|
|
||||||
import { pushQuestionGuideBill } from '@/service/common/bill/push';
|
import { pushQuestionGuideBill } from '@/service/common/bill/push';
|
||||||
import { defaultQGModel } from '@/pages/api/system/getInitData';
|
import { defaultQGModel } from '@/pages/api/system/getInitData';
|
||||||
|
import { createQuestionGuide } from '@fastgpt/core/ai/functions/createQuestionGuide';
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
try {
|
try {
|
||||||
await connectToDatabase();
|
await connectToDatabase();
|
||||||
const { messages } = req.body as CreateQuestionGuideProps;
|
const { messages } = req.body as CreateQuestionGuideProps;
|
||||||
const { user } = await authUser({ req, authToken: true, authApiKey: true, authBalance: true });
|
const { user } = await authUser({
|
||||||
|
req,
|
||||||
|
authOutLink: true,
|
||||||
|
authToken: true,
|
||||||
|
authApiKey: true,
|
||||||
|
authBalance: true
|
||||||
|
});
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new Error('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
const qgModel = global.qgModel || defaultQGModel;
|
|
||||||
|
|
||||||
const chatAPI = getAIChatApi(user.openaiAccount);
|
const { result, tokens } = await createQuestionGuide({
|
||||||
|
messages,
|
||||||
const { data } = await chatAPI.createChatCompletion({
|
model: (global.qgModel || defaultQGModel).model
|
||||||
model: qgModel.model,
|
|
||||||
temperature: 0,
|
|
||||||
max_tokens: 200,
|
|
||||||
messages: [
|
|
||||||
...messages,
|
|
||||||
{
|
|
||||||
role: 'user',
|
|
||||||
content: Prompt_QuestionGuide
|
|
||||||
}
|
|
||||||
],
|
|
||||||
stream: false
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const answer = data.choices?.[0].message?.content || '';
|
jsonRes(res, {
|
||||||
const totalTokens = data.usage?.total_tokens || 0;
|
data: result
|
||||||
|
});
|
||||||
|
|
||||||
const start = answer.indexOf('[');
|
pushQuestionGuideBill({
|
||||||
const end = answer.lastIndexOf(']');
|
tokens: tokens,
|
||||||
|
userId: user._id
|
||||||
if (start === -1 || end === -1) {
|
});
|
||||||
return jsonRes(res, {
|
|
||||||
data: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const jsonStr = answer
|
|
||||||
.substring(start, end + 1)
|
|
||||||
.replace(/(\\n|\\)/g, '')
|
|
||||||
.replace(/ /g, '');
|
|
||||||
|
|
||||||
try {
|
|
||||||
jsonRes(res, {
|
|
||||||
data: JSON.parse(jsonStr)
|
|
||||||
});
|
|
||||||
|
|
||||||
pushQuestionGuideBill({
|
|
||||||
tokens: totalTokens,
|
|
||||||
userId: user._id
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
} catch (error) {
|
|
||||||
return jsonRes(res, {
|
|
||||||
data: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
jsonRes(res, {
|
jsonRes(res, {
|
||||||
code: 500,
|
code: 500,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
|||||||
import { jsonRes } from '@/service/response';
|
import { jsonRes } from '@/service/response';
|
||||||
import { authBalanceByUid, authUser } from '@/service/utils/auth';
|
import { authBalanceByUid, authUser } from '@/service/utils/auth';
|
||||||
import { withNextCors } from '@/service/utils/tools';
|
import { withNextCors } from '@/service/utils/tools';
|
||||||
import { getAIChatApi, axiosConfig } from '@fastgpt/core/aiApi/config';
|
import { getAIChatApi, axiosConfig } from '@fastgpt/core/ai/config';
|
||||||
import { pushGenerateVectorBill } from '@/service/common/bill/push';
|
import { pushGenerateVectorBill } from '@/service/common/bill/push';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { User } from '@/service/models/user';
|
|||||||
import { connectToDatabase } from '@/service/mongo';
|
import { connectToDatabase } from '@/service/mongo';
|
||||||
import { authUser } from '@/service/utils/auth';
|
import { authUser } from '@/service/utils/auth';
|
||||||
import { UserUpdateParams } from '@/types/user';
|
import { UserUpdateParams } from '@/types/user';
|
||||||
import { axiosConfig, getAIChatApi, openaiBaseUrl } from '@fastgpt/core/aiApi/config';
|
import { axiosConfig, getAIChatApi, openaiBaseUrl } from '@fastgpt/core/ai/config';
|
||||||
|
|
||||||
/* update user info */
|
/* update user info */
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
|
|||||||
@ -12,9 +12,10 @@ import {
|
|||||||
dispatchAnswer,
|
dispatchAnswer,
|
||||||
dispatchClassifyQuestion,
|
dispatchClassifyQuestion,
|
||||||
dispatchContentExtract,
|
dispatchContentExtract,
|
||||||
dispatchHttpRequest
|
dispatchHttpRequest,
|
||||||
|
dispatchAppRequest
|
||||||
} from '@/service/moduleDispatch';
|
} from '@/service/moduleDispatch';
|
||||||
import type { CreateChatCompletionRequest } from '@fastgpt/core/aiApi/type';
|
import type { CreateChatCompletionRequest } from '@fastgpt/core/ai/type';
|
||||||
import type { MessageItemType } from '@/types/core/chat/type';
|
import type { MessageItemType } from '@/types/core/chat/type';
|
||||||
import { gptMessage2ChatType, textAdaptGptResponse } from '@/utils/adapt';
|
import { gptMessage2ChatType, textAdaptGptResponse } from '@/utils/adapt';
|
||||||
import { getChatHistory } from './getHistory';
|
import { getChatHistory } from './getHistory';
|
||||||
@ -325,14 +326,19 @@ export async function dispatchModules({
|
|||||||
responseData
|
responseData
|
||||||
}: {
|
}: {
|
||||||
answerText?: string;
|
answerText?: string;
|
||||||
responseData?: ChatHistoryItemResType;
|
responseData?: ChatHistoryItemResType | ChatHistoryItemResType[];
|
||||||
}) {
|
}) {
|
||||||
const time = Date.now();
|
const time = Date.now();
|
||||||
responseData &&
|
if (responseData) {
|
||||||
chatResponse.push({
|
if (Array.isArray(responseData)) {
|
||||||
...responseData,
|
chatResponse = chatResponse.concat(responseData);
|
||||||
runningTime: +((time - runningTime) / 1000).toFixed(2)
|
} else {
|
||||||
});
|
chatResponse.push({
|
||||||
|
...responseData,
|
||||||
|
runningTime: +((time - runningTime) / 1000).toFixed(2)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
runningTime = time;
|
runningTime = time;
|
||||||
chatAnswerText += answerText;
|
chatAnswerText += answerText;
|
||||||
}
|
}
|
||||||
@ -411,7 +417,7 @@ export async function dispatchModules({
|
|||||||
variables,
|
variables,
|
||||||
moduleName: module.name,
|
moduleName: module.name,
|
||||||
outputs: module.outputs,
|
outputs: module.outputs,
|
||||||
userOpenaiAccount: user?.openaiAccount,
|
user,
|
||||||
inputs: params
|
inputs: params
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -424,7 +430,8 @@ export async function dispatchModules({
|
|||||||
[FlowModuleTypeEnum.kbSearchNode]: dispatchKBSearch,
|
[FlowModuleTypeEnum.kbSearchNode]: dispatchKBSearch,
|
||||||
[FlowModuleTypeEnum.classifyQuestion]: dispatchClassifyQuestion,
|
[FlowModuleTypeEnum.classifyQuestion]: dispatchClassifyQuestion,
|
||||||
[FlowModuleTypeEnum.contentExtract]: dispatchContentExtract,
|
[FlowModuleTypeEnum.contentExtract]: dispatchContentExtract,
|
||||||
[FlowModuleTypeEnum.httpRequest]: dispatchHttpRequest
|
[FlowModuleTypeEnum.httpRequest]: dispatchHttpRequest,
|
||||||
|
[FlowModuleTypeEnum.app]: dispatchAppRequest
|
||||||
};
|
};
|
||||||
if (callbackMap[module.flowType]) {
|
if (callbackMap[module.flowType]) {
|
||||||
return callbackMap[module.flowType](props);
|
return callbackMap[module.flowType](props);
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { NodeProps } from 'reactflow';
|
||||||
|
import NodeCard from '../modules/NodeCard';
|
||||||
|
import { FlowModuleItemType } from '@/types/core/app/flow';
|
||||||
|
import Divider from '../modules/Divider';
|
||||||
|
import Container from '../modules/Container';
|
||||||
|
import RenderInput from '../render/RenderInput';
|
||||||
|
import RenderOutput from '../render/RenderOutput';
|
||||||
|
|
||||||
|
const NodeAPP = ({ data }: NodeProps<FlowModuleItemType>) => {
|
||||||
|
const { moduleId, inputs, outputs } = data;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NodeCard minW={'350px'} {...data}>
|
||||||
|
<Container borderTop={'2px solid'} borderTopColor={'myGray.200'}>
|
||||||
|
<RenderInput moduleId={moduleId} flowInputList={inputs} />
|
||||||
|
</Container>
|
||||||
|
<Divider text="Output" />
|
||||||
|
<Container>
|
||||||
|
<RenderOutput moduleId={moduleId} flowOutputList={outputs} />
|
||||||
|
</Container>
|
||||||
|
</NodeCard>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default React.memo(NodeAPP);
|
||||||
@ -35,6 +35,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
|||||||
|
|
||||||
type OnChange<ChangesType> = (changes: ChangesType[]) => void;
|
type OnChange<ChangesType> = (changes: ChangesType[]) => void;
|
||||||
export type useFlowStoreType = {
|
export type useFlowStoreType = {
|
||||||
|
appId: string;
|
||||||
reactFlowWrapper: null | React.RefObject<HTMLDivElement>;
|
reactFlowWrapper: null | React.RefObject<HTMLDivElement>;
|
||||||
nodes: Node<FlowModuleItemType, string | undefined>[];
|
nodes: Node<FlowModuleItemType, string | undefined>[];
|
||||||
setNodes: Dispatch<SetStateAction<Node<FlowModuleItemType, string | undefined>[]>>;
|
setNodes: Dispatch<SetStateAction<Node<FlowModuleItemType, string | undefined>[]>>;
|
||||||
@ -58,6 +59,7 @@ export type useFlowStoreType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const StateContext = createContext<useFlowStoreType>({
|
const StateContext = createContext<useFlowStoreType>({
|
||||||
|
appId: '',
|
||||||
reactFlowWrapper: null,
|
reactFlowWrapper: null,
|
||||||
nodes: [],
|
nodes: [],
|
||||||
setNodes: function (
|
setNodes: function (
|
||||||
@ -109,7 +111,7 @@ const StateContext = createContext<useFlowStoreType>({
|
|||||||
});
|
});
|
||||||
export const useFlowStore = () => useContext(StateContext);
|
export const useFlowStore = () => useContext(StateContext);
|
||||||
|
|
||||||
export const FlowProvider = ({ children }: { children: React.ReactNode }) => {
|
export const FlowProvider = ({ appId, children }: { appId: string; children: React.ReactNode }) => {
|
||||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
@ -209,7 +211,6 @@ export const FlowProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
||||||
const mouseX = (position.x - reactFlowBounds.left - x) / zoom - 100;
|
const mouseX = (position.x - reactFlowBounds.left - x) / zoom - 100;
|
||||||
const mouseY = (position.y - reactFlowBounds.top - y) / zoom;
|
const mouseY = (position.y - reactFlowBounds.top - y) / zoom;
|
||||||
console.log(template);
|
|
||||||
setNodes((state) =>
|
setNodes((state) =>
|
||||||
state.concat(
|
state.concat(
|
||||||
appModule2FlowNode({
|
appModule2FlowNode({
|
||||||
@ -328,6 +329,7 @@ export const FlowProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
|
appId,
|
||||||
reactFlowWrapper,
|
reactFlowWrapper,
|
||||||
nodes,
|
nodes,
|
||||||
setNodes,
|
setNodes,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import type { FlowInputItemType } from '@/types/core/app/flow';
|
import type { FlowInputItemType, SelectAppItemType } from '@/types/core/app/flow';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Textarea,
|
Textarea,
|
||||||
@ -9,7 +9,10 @@ import {
|
|||||||
NumberInputStepper,
|
NumberInputStepper,
|
||||||
NumberIncrementStepper,
|
NumberIncrementStepper,
|
||||||
NumberDecrementStepper,
|
NumberDecrementStepper,
|
||||||
Flex
|
Flex,
|
||||||
|
useDisclosure,
|
||||||
|
Button,
|
||||||
|
useTheme
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FlowInputItemTypeEnum } from '@/constants/flow';
|
import { FlowInputItemTypeEnum } from '@/constants/flow';
|
||||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||||
@ -20,7 +23,9 @@ import MyTooltip from '@/components/MyTooltip';
|
|||||||
import TargetHandle from './TargetHandle';
|
import TargetHandle from './TargetHandle';
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
const SetInputFieldModal = dynamic(() => import('../modules/SetInputFieldModal'));
|
const SetInputFieldModal = dynamic(() => import('../modules/SetInputFieldModal'));
|
||||||
|
const SelectAppModal = dynamic(() => import('../../../SelectAppModal'));
|
||||||
import { useFlowStore } from '../Provider';
|
import { useFlowStore } from '../Provider';
|
||||||
|
import Avatar from '@/components/Avatar';
|
||||||
|
|
||||||
export const Label = ({
|
export const Label = ({
|
||||||
moduleId,
|
moduleId,
|
||||||
@ -141,6 +146,7 @@ const RenderInput = ({
|
|||||||
CustomComponent?: Record<string, (e: FlowInputItemType) => React.ReactNode>;
|
CustomComponent?: Record<string, (e: FlowInputItemType) => React.ReactNode>;
|
||||||
}) => {
|
}) => {
|
||||||
const { onChangeNode } = useFlowStore();
|
const { onChangeNode } = useFlowStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{flowInputList.map(
|
{flowInputList.map(
|
||||||
@ -253,6 +259,9 @@ const RenderInput = ({
|
|||||||
{item.type === FlowInputItemTypeEnum.custom && CustomComponent[item.key] && (
|
{item.type === FlowInputItemTypeEnum.custom && CustomComponent[item.key] && (
|
||||||
<>{CustomComponent[item.key]({ ...item })}</>
|
<>{CustomComponent[item.key]({ ...item })}</>
|
||||||
)}
|
)}
|
||||||
|
{item.type === FlowInputItemTypeEnum.selectApp && (
|
||||||
|
<RenderSelectApp app={item} moduleId={moduleId} />
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
@ -262,3 +271,54 @@ const RenderInput = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default React.memo(RenderInput);
|
export default React.memo(RenderInput);
|
||||||
|
|
||||||
|
function RenderSelectApp({ app, moduleId }: { app: FlowInputItemType; moduleId: string }) {
|
||||||
|
const { onChangeNode, appId } = useFlowStore();
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
const {
|
||||||
|
isOpen: isOpenSelectApp,
|
||||||
|
onOpen: onOpenSelectApp,
|
||||||
|
onClose: onCloseSelectApp
|
||||||
|
} = useDisclosure();
|
||||||
|
|
||||||
|
const value = app.value as SelectAppItemType | undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box onClick={onOpenSelectApp}>
|
||||||
|
{!value ? (
|
||||||
|
<Button variant={'base'} w={'100%'}>
|
||||||
|
选择应用
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Flex alignItems={'center'} border={theme.borders.base} borderRadius={'md'} px={3} py={2}>
|
||||||
|
<Avatar src={value?.logo} />
|
||||||
|
<Box fontWeight={'bold'} ml={1}>
|
||||||
|
{value?.name}
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{isOpenSelectApp && (
|
||||||
|
<SelectAppModal
|
||||||
|
defaultApps={app.value?.id ? [app.value.id] : []}
|
||||||
|
filterApps={[appId]}
|
||||||
|
onClose={onCloseSelectApp}
|
||||||
|
onSuccess={(e) => {
|
||||||
|
onChangeNode({
|
||||||
|
moduleId,
|
||||||
|
type: 'inputs',
|
||||||
|
key: 'app',
|
||||||
|
value: {
|
||||||
|
...app,
|
||||||
|
value: e[0]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ const NodeVariable = dynamic(() => import('./components/Nodes/NodeVariable'));
|
|||||||
const NodeUserGuide = dynamic(() => import('./components/Nodes/NodeUserGuide'));
|
const NodeUserGuide = dynamic(() => import('./components/Nodes/NodeUserGuide'));
|
||||||
const NodeExtract = dynamic(() => import('./components/Nodes/NodeExtract'));
|
const NodeExtract = dynamic(() => import('./components/Nodes/NodeExtract'));
|
||||||
const NodeHttp = dynamic(() => import('./components/Nodes/NodeHttp'));
|
const NodeHttp = dynamic(() => import('./components/Nodes/NodeHttp'));
|
||||||
|
const NodeAPP = dynamic(() => import('./components/Nodes/NodeAPP'));
|
||||||
|
|
||||||
import 'reactflow/dist/style.css';
|
import 'reactflow/dist/style.css';
|
||||||
|
|
||||||
@ -52,7 +53,8 @@ const nodeTypes = {
|
|||||||
[FlowModuleTypeEnum.answerNode]: NodeAnswer,
|
[FlowModuleTypeEnum.answerNode]: NodeAnswer,
|
||||||
[FlowModuleTypeEnum.classifyQuestion]: NodeCQNode,
|
[FlowModuleTypeEnum.classifyQuestion]: NodeCQNode,
|
||||||
[FlowModuleTypeEnum.contentExtract]: NodeExtract,
|
[FlowModuleTypeEnum.contentExtract]: NodeExtract,
|
||||||
[FlowModuleTypeEnum.httpRequest]: NodeHttp
|
[FlowModuleTypeEnum.httpRequest]: NodeHttp,
|
||||||
|
[FlowModuleTypeEnum.app]: NodeAPP
|
||||||
// [FlowModuleTypeEnum.empty]: EmptyModule
|
// [FlowModuleTypeEnum.empty]: EmptyModule
|
||||||
};
|
};
|
||||||
const edgeTypes = {
|
const edgeTypes = {
|
||||||
@ -116,8 +118,17 @@ function FlowHeader({ app, onCloseSettings }: Props & {}) {
|
|||||||
|
|
||||||
const { mutate: onclickSave, isLoading } = useRequest({
|
const { mutate: onclickSave, isLoading } = useRequest({
|
||||||
mutationFn: () => {
|
mutationFn: () => {
|
||||||
|
const modules = flow2AppModules();
|
||||||
|
// check required connect
|
||||||
|
for (let i = 0; i < modules.length; i++) {
|
||||||
|
const item = modules[i];
|
||||||
|
if (item.inputs.find((input) => input.required && !input.connected)) {
|
||||||
|
return Promise.reject(`【${item.name}】存在未连接的必填输入`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return updateAppDetail(app._id, {
|
return updateAppDetail(app._id, {
|
||||||
modules: flow2AppModules(),
|
modules: modules,
|
||||||
type: AppTypeEnum.advanced
|
type: AppTypeEnum.advanced
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -314,7 +325,7 @@ const Flow = (data: Props) => {
|
|||||||
return (
|
return (
|
||||||
<Box h={'100%'} position={'fixed'} zIndex={999} top={0} left={0} right={0} bottom={0}>
|
<Box h={'100%'} position={'fixed'} zIndex={999} top={0} left={0} right={0} bottom={0}>
|
||||||
<ReactFlowProvider>
|
<ReactFlowProvider>
|
||||||
<FlowProvider>
|
<FlowProvider appId={data?.app?._id}>
|
||||||
<Flex h={'100%'} flexDirection={'column'} bg={'#fff'}>
|
<Flex h={'100%'} flexDirection={'column'} bg={'#fff'}>
|
||||||
{!!data.app._id && <AppEdit {...data} />}
|
{!!data.app._id && <AppEdit {...data} />}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@ -69,7 +69,12 @@ export const DatasetSelectModal = ({
|
|||||||
tips={'仅能选择同一个索引模型的知识库'}
|
tips={'仅能选择同一个索引模型的知识库'}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
>
|
>
|
||||||
<ModalBody flex={['1 0 0', '0 0 auto']} maxH={'80vh'} overflowY={'auto'} userSelect={'none'}>
|
<ModalBody
|
||||||
|
flex={['1 0 0', '1 0 auto']}
|
||||||
|
maxH={'80vh'}
|
||||||
|
overflowY={['auto', 'unset']}
|
||||||
|
userSelect={'none'}
|
||||||
|
>
|
||||||
<Grid gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']} gridGap={3}>
|
<Grid gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']} gridGap={3}>
|
||||||
{filterKbList.selected.map((item) =>
|
{filterKbList.selected.map((item) =>
|
||||||
(() => {
|
(() => {
|
||||||
|
|||||||
@ -287,7 +287,6 @@ function DetailLogsModal({
|
|||||||
<Box pt={2} flex={'1 0 0'}>
|
<Box pt={2} flex={'1 0 0'}>
|
||||||
<ChatBox
|
<ChatBox
|
||||||
ref={ChatBoxRef}
|
ref={ChatBoxRef}
|
||||||
chatId={chatId}
|
|
||||||
appAvatar={chat?.app.avatar}
|
appAvatar={chat?.app.avatar}
|
||||||
userAvatar={HUMAN_ICON}
|
userAvatar={HUMAN_ICON}
|
||||||
feedbackType={'admin'}
|
feedbackType={'admin'}
|
||||||
|
|||||||
110
projects/app/src/pages/app/detail/components/SelectAppModal.tsx
Normal file
110
projects/app/src/pages/app/detail/components/SelectAppModal.tsx
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { ModalBody, Flex, Box, useTheme, ModalFooter, Button } from '@chakra-ui/react';
|
||||||
|
import MyModal from '@/components/MyModal';
|
||||||
|
import { getMyModels } from '@/api/app';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import type { SelectAppItemType } from '@/types/core/app/flow';
|
||||||
|
import Avatar from '@/components/Avatar';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useLoading } from '@/hooks/useLoading';
|
||||||
|
|
||||||
|
const SelectAppModal = ({
|
||||||
|
defaultApps = [],
|
||||||
|
filterApps = [],
|
||||||
|
max = 1,
|
||||||
|
onClose,
|
||||||
|
onSuccess
|
||||||
|
}: {
|
||||||
|
defaultApps: string[];
|
||||||
|
filterApps?: string[];
|
||||||
|
max?: number;
|
||||||
|
onClose: () => void;
|
||||||
|
onSuccess: (e: SelectAppItemType[]) => void;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { Loading } = useLoading();
|
||||||
|
const theme = useTheme();
|
||||||
|
const [selectedApps, setSelectedApps] = React.useState<string[]>(defaultApps);
|
||||||
|
/* 加载模型 */
|
||||||
|
const { data = [], isLoading } = useQuery(['loadMyApos'], () => getMyModels());
|
||||||
|
|
||||||
|
const apps = useMemo(
|
||||||
|
() => data.filter((app) => !filterApps.includes(app._id)),
|
||||||
|
[data, filterApps]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MyModal
|
||||||
|
isOpen
|
||||||
|
title={`选择应用${max > 1 ? `(${selectedApps.length}/${max})` : ''}`}
|
||||||
|
onClose={onClose}
|
||||||
|
w={'700px'}
|
||||||
|
position={'relative'}
|
||||||
|
>
|
||||||
|
<ModalBody
|
||||||
|
minH={'300px'}
|
||||||
|
display={'grid'}
|
||||||
|
gridTemplateColumns={['1fr', 'repeat(3,1fr)']}
|
||||||
|
gridGap={4}
|
||||||
|
>
|
||||||
|
{apps.map((app) => (
|
||||||
|
<Flex
|
||||||
|
key={app._id}
|
||||||
|
alignItems={'center'}
|
||||||
|
border={theme.borders.base}
|
||||||
|
borderRadius={'md'}
|
||||||
|
px={1}
|
||||||
|
py={2}
|
||||||
|
cursor={'pointer'}
|
||||||
|
{...(selectedApps.includes(app._id)
|
||||||
|
? {
|
||||||
|
bg: 'myBlue.200',
|
||||||
|
onClick: () => {
|
||||||
|
setSelectedApps(selectedApps.filter((e) => e !== app._id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
onClick: () => {
|
||||||
|
if (max === 1) {
|
||||||
|
setSelectedApps([app._id]);
|
||||||
|
} else if (selectedApps.length < max) {
|
||||||
|
setSelectedApps([...selectedApps, app._id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Avatar src={app.avatar} w={['16px', '22px']} />
|
||||||
|
<Box fontWeight={'bold'} ml={1}>
|
||||||
|
{app.name}
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
))}
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button variant={'base'} onClick={onClose}>
|
||||||
|
{t('Cancel')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
ml={2}
|
||||||
|
onClick={() => {
|
||||||
|
onSuccess(
|
||||||
|
apps
|
||||||
|
.filter((app) => selectedApps.includes(app._id))
|
||||||
|
.map((app) => ({
|
||||||
|
id: app._id,
|
||||||
|
name: app.name,
|
||||||
|
logo: app.avatar
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('Confirm')}
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
<Loading loading={isLoading} fixed={false} />
|
||||||
|
</MyModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default React.memo(SelectAppModal);
|
||||||
@ -64,7 +64,7 @@ const MyApps = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/* 加载模型 */
|
/* 加载模型 */
|
||||||
useQuery(['loadModels'], () => loadMyApps(true), {
|
useQuery(['loadApps'], () => loadMyApps(true), {
|
||||||
refetchOnMount: true
|
refetchOnMount: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import { useRouter } from 'next/router';
|
|||||||
const ToolMenu = ({ history }: { history: ChatItemType[] }) => {
|
const ToolMenu = ({ history }: { history: ChatItemType[] }) => {
|
||||||
const { onExportChat } = useChatBox();
|
const { onExportChat } = useChatBox();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { appId, shareId } = router.query;
|
|
||||||
|
|
||||||
const menuList = useMemo(
|
const menuList = useMemo(
|
||||||
() => [
|
() => [
|
||||||
@ -18,8 +17,8 @@ const ToolMenu = ({ history }: { history: ChatItemType[] }) => {
|
|||||||
onClick: () => {
|
onClick: () => {
|
||||||
router.replace({
|
router.replace({
|
||||||
query: {
|
query: {
|
||||||
appId,
|
...router.query,
|
||||||
shareId
|
chatId: ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -36,7 +35,7 @@ const ToolMenu = ({ history }: { history: ChatItemType[] }) => {
|
|||||||
},
|
},
|
||||||
{ icon: 'pdf', label: 'PDF导出', onClick: () => onExportChat({ type: 'pdf', history }) }
|
{ icon: 'pdf', label: 'PDF导出', onClick: () => onExportChat({ type: 'pdf', history }) }
|
||||||
],
|
],
|
||||||
[appId, history, onExportChat, router, shareId]
|
[history, onExportChat, router]
|
||||||
);
|
);
|
||||||
|
|
||||||
return history.length > 0 ? (
|
return history.length > 0 ? (
|
||||||
|
|||||||
@ -358,7 +358,6 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
|
|||||||
<ChatBox
|
<ChatBox
|
||||||
ref={ChatBoxRef}
|
ref={ChatBoxRef}
|
||||||
showEmptyIntro
|
showEmptyIntro
|
||||||
chatId={chatId}
|
|
||||||
appAvatar={chatData.app.avatar}
|
appAvatar={chatData.app.avatar}
|
||||||
userAvatar={userInfo?.avatar}
|
userAvatar={userInfo?.avatar}
|
||||||
userGuideModule={chatData.app?.userGuideModule}
|
userGuideModule={chatData.app?.userGuideModule}
|
||||||
|
|||||||
@ -24,10 +24,12 @@ import { serviceSideProps } from '@/utils/web/i18n';
|
|||||||
const OutLink = ({
|
const OutLink = ({
|
||||||
shareId,
|
shareId,
|
||||||
chatId,
|
chatId,
|
||||||
|
showHistory,
|
||||||
authToken
|
authToken
|
||||||
}: {
|
}: {
|
||||||
shareId: string;
|
shareId: string;
|
||||||
chatId: string;
|
chatId: string;
|
||||||
|
showHistory: '0' | '1';
|
||||||
authToken?: string;
|
authToken?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -89,9 +91,8 @@ const OutLink = ({
|
|||||||
forbidRefresh.current = true;
|
forbidRefresh.current = true;
|
||||||
router.replace({
|
router.replace({
|
||||||
query: {
|
query: {
|
||||||
shareId,
|
...router.query,
|
||||||
chatId: completionChatId,
|
chatId: completionChatId
|
||||||
authToken
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -174,59 +175,58 @@ const OutLink = ({
|
|||||||
<title>{shareChatData.app.name}</title>
|
<title>{shareChatData.app.name}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<Flex h={'100%'} flexDirection={['column', 'row']}>
|
<Flex h={'100%'} flexDirection={['column', 'row']}>
|
||||||
{((children: React.ReactNode) => {
|
{showHistory === '1'
|
||||||
return isPc ? (
|
? ((children: React.ReactNode) => {
|
||||||
<SideBar>{children}</SideBar>
|
return isPc ? (
|
||||||
) : (
|
<SideBar>{children}</SideBar>
|
||||||
<Drawer
|
) : (
|
||||||
isOpen={isOpenSlider}
|
<Drawer
|
||||||
placement="left"
|
isOpen={isOpenSlider}
|
||||||
autoFocus={false}
|
placement="left"
|
||||||
size={'xs'}
|
autoFocus={false}
|
||||||
onClose={onCloseSlider}
|
size={'xs'}
|
||||||
>
|
onClose={onCloseSlider}
|
||||||
<DrawerOverlay backgroundColor={'rgba(255,255,255,0.5)'} />
|
>
|
||||||
<DrawerContent maxWidth={'250px'} boxShadow={'2px 0 10px rgba(0,0,0,0.15)'}>
|
<DrawerOverlay backgroundColor={'rgba(255,255,255,0.5)'} />
|
||||||
{children}
|
<DrawerContent maxWidth={'250px'} boxShadow={'2px 0 10px rgba(0,0,0,0.15)'}>
|
||||||
</DrawerContent>
|
{children}
|
||||||
</Drawer>
|
</DrawerContent>
|
||||||
);
|
</Drawer>
|
||||||
})(
|
);
|
||||||
<ChatHistorySlider
|
})(
|
||||||
appName={shareChatData.app.name}
|
<ChatHistorySlider
|
||||||
appAvatar={shareChatData.app.avatar}
|
appName={shareChatData.app.name}
|
||||||
activeChatId={chatId}
|
appAvatar={shareChatData.app.avatar}
|
||||||
history={history.map((item) => ({
|
activeChatId={chatId}
|
||||||
id: item.chatId,
|
history={history.map((item) => ({
|
||||||
title: item.title
|
id: item.chatId,
|
||||||
}))}
|
title: item.title
|
||||||
onClose={onCloseSlider}
|
}))}
|
||||||
onChangeChat={(chatId) => {
|
onClose={onCloseSlider}
|
||||||
console.log(chatId);
|
onChangeChat={(chatId) => {
|
||||||
|
router.replace({
|
||||||
router.replace({
|
query: {
|
||||||
query: {
|
...router.query,
|
||||||
chatId: chatId || '',
|
chatId: chatId || ''
|
||||||
shareId,
|
}
|
||||||
authToken
|
});
|
||||||
}
|
if (!isPc) {
|
||||||
});
|
onCloseSlider();
|
||||||
if (!isPc) {
|
}
|
||||||
onCloseSlider();
|
}}
|
||||||
}
|
onDelHistory={delOneShareHistoryByChatId}
|
||||||
}}
|
onClearHistory={() => {
|
||||||
onDelHistory={delOneShareHistoryByChatId}
|
delManyShareChatHistoryByShareId(shareId);
|
||||||
onClearHistory={() => {
|
router.replace({
|
||||||
delManyShareChatHistoryByShareId(shareId);
|
query: {
|
||||||
router.replace({
|
...router.query,
|
||||||
query: {
|
chatId: ''
|
||||||
shareId,
|
}
|
||||||
authToken
|
});
|
||||||
}
|
}}
|
||||||
});
|
/>
|
||||||
}}
|
)
|
||||||
/>
|
: null}
|
||||||
)}
|
|
||||||
|
|
||||||
{/* chat container */}
|
{/* chat container */}
|
||||||
<Flex
|
<Flex
|
||||||
@ -276,10 +276,11 @@ const OutLink = ({
|
|||||||
export async function getServerSideProps(context: any) {
|
export async function getServerSideProps(context: any) {
|
||||||
const shareId = context?.query?.shareId || '';
|
const shareId = context?.query?.shareId || '';
|
||||||
const chatId = context?.query?.chatId || '';
|
const chatId = context?.query?.chatId || '';
|
||||||
|
const showHistory = context?.query?.showHistory || '1';
|
||||||
const authToken = context?.query?.authToken || '';
|
const authToken = context?.query?.authToken || '';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: { shareId, chatId, authToken, ...(await serviceSideProps(context)) }
|
props: { shareId, chatId, showHistory, authToken, ...(await serviceSideProps(context)) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import { TrainingModeEnum } from '@/constants/plugin';
|
|||||||
import { ERROR_ENUM } from '../errorCode';
|
import { ERROR_ENUM } from '../errorCode';
|
||||||
import { sendInform } from '@/pages/api/user/inform/send';
|
import { sendInform } from '@/pages/api/user/inform/send';
|
||||||
import { authBalanceByUid } from '../utils/auth';
|
import { authBalanceByUid } from '../utils/auth';
|
||||||
import { axiosConfig, getAIChatApi } from '@fastgpt/core/aiApi/config';
|
import { axiosConfig, getAIChatApi } from '@fastgpt/core/ai/config';
|
||||||
import type { ChatCompletionRequestMessage } from '@fastgpt/core/aiApi/type';
|
import type { ChatCompletionRequestMessage } from '@fastgpt/core/ai/type';
|
||||||
import { addLog } from '../utils/tools';
|
import { addLog } from '../utils/tools';
|
||||||
import { splitText2Chunks } from '@/utils/file';
|
import { splitText2Chunks } from '@/utils/file';
|
||||||
import { replaceVariable } from '@/utils/common/tools/text';
|
import { replaceVariable } from '@/utils/common/tools/text';
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { adaptChat2GptMessages } from '@/utils/common/adapt/message';
|
|||||||
import { ChatContextFilter } from '@/service/common/tiktoken';
|
import { ChatContextFilter } from '@/service/common/tiktoken';
|
||||||
import type { ChatHistoryItemResType, ChatItemType } from '@/types/chat';
|
import type { ChatHistoryItemResType, ChatItemType } from '@/types/chat';
|
||||||
import { ChatRoleEnum, TaskResponseKeyEnum } from '@/constants/chat';
|
import { ChatRoleEnum, TaskResponseKeyEnum } from '@/constants/chat';
|
||||||
import { getAIChatApi, axiosConfig } from '@fastgpt/core/aiApi/config';
|
import { getAIChatApi, axiosConfig } from '@fastgpt/core/ai/config';
|
||||||
import type { ClassifyQuestionAgentItemType } from '@/types/app';
|
import type { ClassifyQuestionAgentItemType } from '@/types/app';
|
||||||
import { SystemInputEnum } from '@/constants/app';
|
import { SystemInputEnum } from '@/constants/app';
|
||||||
import { SpecialInputKeyEnum } from '@/constants/flow';
|
import { SpecialInputKeyEnum } from '@/constants/flow';
|
||||||
@ -29,7 +29,7 @@ const agentFunName = 'agent_user_question';
|
|||||||
export const dispatchClassifyQuestion = async (props: Props): Promise<CQResponse> => {
|
export const dispatchClassifyQuestion = async (props: Props): Promise<CQResponse> => {
|
||||||
const {
|
const {
|
||||||
moduleName,
|
moduleName,
|
||||||
userOpenaiAccount,
|
user,
|
||||||
inputs: { agents, userChatInput }
|
inputs: { agents, userChatInput }
|
||||||
} = props as Props;
|
} = props as Props;
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ export const dispatchClassifyQuestion = async (props: Props): Promise<CQResponse
|
|||||||
[TaskResponseKeyEnum.responseData]: {
|
[TaskResponseKeyEnum.responseData]: {
|
||||||
moduleType: FlowModuleTypeEnum.classifyQuestion,
|
moduleType: FlowModuleTypeEnum.classifyQuestion,
|
||||||
moduleName,
|
moduleName,
|
||||||
price: userOpenaiAccount?.key ? 0 : cqModel.price * tokens,
|
price: user.openaiAccount?.key ? 0 : cqModel.price * tokens,
|
||||||
model: cqModel.name || '',
|
model: cqModel.name || '',
|
||||||
tokens,
|
tokens,
|
||||||
cqList: agents,
|
cqList: agents,
|
||||||
@ -63,7 +63,7 @@ export const dispatchClassifyQuestion = async (props: Props): Promise<CQResponse
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function functionCall({
|
async function functionCall({
|
||||||
userOpenaiAccount,
|
user,
|
||||||
inputs: { agents, systemPrompt, history = [], userChatInput }
|
inputs: { agents, systemPrompt, history = [], userChatInput }
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const cqModel = global.cqModel;
|
const cqModel = global.cqModel;
|
||||||
@ -105,7 +105,7 @@ async function functionCall({
|
|||||||
required: ['type']
|
required: ['type']
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const chatAPI = getAIChatApi(userOpenaiAccount);
|
const chatAPI = getAIChatApi(user.openaiAccount);
|
||||||
|
|
||||||
const response = await chatAPI.createChatCompletion(
|
const response = await chatAPI.createChatCompletion(
|
||||||
{
|
{
|
||||||
@ -116,7 +116,7 @@ async function functionCall({
|
|||||||
functions: [agentFunction]
|
functions: [agentFunction]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...axiosConfig(userOpenaiAccount)
|
...axiosConfig(user.openaiAccount)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ async function functionCall({
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function completions({
|
async function completions({
|
||||||
userOpenaiAccount,
|
user,
|
||||||
inputs: { agents, systemPrompt = '', history = [], userChatInput }
|
inputs: { agents, systemPrompt = '', history = [], userChatInput }
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const extractModel = global.extractModel;
|
const extractModel = global.extractModel;
|
||||||
@ -155,7 +155,7 @@ Human:${userChatInput}`
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const chatAPI = getAIChatApi(userOpenaiAccount);
|
const chatAPI = getAIChatApi(user.openaiAccount);
|
||||||
|
|
||||||
const { data } = await chatAPI.createChatCompletion(
|
const { data } = await chatAPI.createChatCompletion(
|
||||||
{
|
{
|
||||||
@ -166,7 +166,7 @@ Human:${userChatInput}`
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
timeout: 480000,
|
timeout: 480000,
|
||||||
...axiosConfig(userOpenaiAccount)
|
...axiosConfig(user.openaiAccount)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const answer = data.choices?.[0].message?.content || '';
|
const answer = data.choices?.[0].message?.content || '';
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { adaptChat2GptMessages } from '@/utils/common/adapt/message';
|
|||||||
import { ChatContextFilter } from '@/service/common/tiktoken';
|
import { ChatContextFilter } from '@/service/common/tiktoken';
|
||||||
import type { ChatHistoryItemResType, ChatItemType } from '@/types/chat';
|
import type { ChatHistoryItemResType, ChatItemType } from '@/types/chat';
|
||||||
import { ChatRoleEnum, TaskResponseKeyEnum } from '@/constants/chat';
|
import { ChatRoleEnum, TaskResponseKeyEnum } from '@/constants/chat';
|
||||||
import { getAIChatApi, axiosConfig } from '@fastgpt/core/aiApi/config';
|
import { getAIChatApi, axiosConfig } from '@fastgpt/core/ai/config';
|
||||||
import type { ContextExtractAgentItemType } from '@/types/app';
|
import type { ContextExtractAgentItemType } from '@/types/app';
|
||||||
import { ContextExtractEnum } from '@/constants/flow/flowField';
|
import { ContextExtractEnum } from '@/constants/flow/flowField';
|
||||||
import { FlowModuleTypeEnum } from '@/constants/flow';
|
import { FlowModuleTypeEnum } from '@/constants/flow';
|
||||||
@ -29,7 +29,7 @@ const agentFunName = 'agent_extract_data';
|
|||||||
export async function dispatchContentExtract(props: Props): Promise<Response> {
|
export async function dispatchContentExtract(props: Props): Promise<Response> {
|
||||||
const {
|
const {
|
||||||
moduleName,
|
moduleName,
|
||||||
userOpenaiAccount,
|
user,
|
||||||
inputs: { content, description, extractKeys }
|
inputs: { content, description, extractKeys }
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
|||||||
[TaskResponseKeyEnum.responseData]: {
|
[TaskResponseKeyEnum.responseData]: {
|
||||||
moduleType: FlowModuleTypeEnum.contentExtract,
|
moduleType: FlowModuleTypeEnum.contentExtract,
|
||||||
moduleName,
|
moduleName,
|
||||||
price: userOpenaiAccount?.key ? 0 : extractModel.price * tokens,
|
price: user.openaiAccount?.key ? 0 : extractModel.price * tokens,
|
||||||
model: extractModel.name || '',
|
model: extractModel.name || '',
|
||||||
tokens,
|
tokens,
|
||||||
extractDescription: description,
|
extractDescription: description,
|
||||||
@ -83,7 +83,7 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function functionCall({
|
async function functionCall({
|
||||||
userOpenaiAccount,
|
user,
|
||||||
inputs: { history = [], content, extractKeys, description }
|
inputs: { history = [], content, extractKeys, description }
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const extractModel = global.extractModel;
|
const extractModel = global.extractModel;
|
||||||
@ -126,7 +126,7 @@ async function functionCall({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const chatAPI = getAIChatApi(userOpenaiAccount);
|
const chatAPI = getAIChatApi(user.openaiAccount);
|
||||||
|
|
||||||
const response = await chatAPI.createChatCompletion(
|
const response = await chatAPI.createChatCompletion(
|
||||||
{
|
{
|
||||||
@ -137,7 +137,7 @@ async function functionCall({
|
|||||||
functions: [agentFunction]
|
functions: [agentFunction]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...axiosConfig(userOpenaiAccount)
|
...axiosConfig(user.openaiAccount)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ async function functionCall({
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function completions({
|
async function completions({
|
||||||
userOpenaiAccount,
|
user,
|
||||||
inputs: { history = [], content, extractKeys, description }
|
inputs: { history = [], content, extractKeys, description }
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const extractModel = global.extractModel;
|
const extractModel = global.extractModel;
|
||||||
@ -181,7 +181,7 @@ Human: ${content}`
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const chatAPI = getAIChatApi(userOpenaiAccount);
|
const chatAPI = getAIChatApi(user.openaiAccount);
|
||||||
|
|
||||||
const { data } = await chatAPI.createChatCompletion(
|
const { data } = await chatAPI.createChatCompletion(
|
||||||
{
|
{
|
||||||
@ -192,7 +192,7 @@ Human: ${content}`
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
timeout: 480000,
|
timeout: 480000,
|
||||||
...axiosConfig(userOpenaiAccount)
|
...axiosConfig(user.openaiAccount)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const answer = data.choices?.[0].message?.content || '';
|
const answer = data.choices?.[0].message?.content || '';
|
||||||
|
|||||||
@ -5,13 +5,13 @@ import type { ChatHistoryItemResType } from '@/types/chat';
|
|||||||
import { ChatRoleEnum, sseResponseEventEnum } from '@/constants/chat';
|
import { ChatRoleEnum, sseResponseEventEnum } from '@/constants/chat';
|
||||||
import { SSEParseData, parseStreamChunk } from '@/utils/sse';
|
import { SSEParseData, parseStreamChunk } from '@/utils/sse';
|
||||||
import { textAdaptGptResponse } from '@/utils/adapt';
|
import { textAdaptGptResponse } from '@/utils/adapt';
|
||||||
import { getAIChatApi, axiosConfig } from '@fastgpt/core/aiApi/config';
|
import { getAIChatApi, axiosConfig } from '@fastgpt/core/ai/config';
|
||||||
import { TaskResponseKeyEnum } from '@/constants/chat';
|
import { TaskResponseKeyEnum } from '@/constants/chat';
|
||||||
import { getChatModel } from '@/service/utils/data';
|
import { getChatModel } from '@/service/utils/data';
|
||||||
import { countModelPrice } from '@/service/common/bill/push';
|
import { countModelPrice } from '@/service/common/bill/push';
|
||||||
import { ChatModelItemType } from '@/types/model';
|
import { ChatModelItemType } from '@/types/model';
|
||||||
import { textCensor } from '@/api/service/plugins';
|
import { textCensor } from '@/api/service/plugins';
|
||||||
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/core/aiApi/constant';
|
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/core/ai/constant';
|
||||||
import { AppModuleItemType } from '@/types/app';
|
import { AppModuleItemType } from '@/types/app';
|
||||||
import { countMessagesTokens, sliceMessagesTB } from '@/utils/common/tiktoken';
|
import { countMessagesTokens, sliceMessagesTB } from '@/utils/common/tiktoken';
|
||||||
import { adaptChat2GptMessages } from '@/utils/common/adapt/message';
|
import { adaptChat2GptMessages } from '@/utils/common/adapt/message';
|
||||||
@ -35,6 +35,7 @@ export type ChatProps = ModuleDispatchProps<
|
|||||||
export type ChatResponse = {
|
export type ChatResponse = {
|
||||||
[TaskResponseKeyEnum.answerText]: string;
|
[TaskResponseKeyEnum.answerText]: string;
|
||||||
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType;
|
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType;
|
||||||
|
[TaskResponseKeyEnum.history]: ChatItemType[];
|
||||||
finish: boolean;
|
finish: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
moduleName,
|
moduleName,
|
||||||
stream = false,
|
stream = false,
|
||||||
detail = false,
|
detail = false,
|
||||||
userOpenaiAccount,
|
user,
|
||||||
outputs,
|
outputs,
|
||||||
inputs: {
|
inputs: {
|
||||||
model = global.chatModels[0]?.model,
|
model = global.chatModels[0]?.model,
|
||||||
@ -105,7 +106,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
// FastGPT temperature range: 1~10
|
// FastGPT temperature range: 1~10
|
||||||
temperature = +(modelConstantsData.maxTemperature * (temperature / 10)).toFixed(2);
|
temperature = +(modelConstantsData.maxTemperature * (temperature / 10)).toFixed(2);
|
||||||
temperature = Math.max(temperature, 0.01);
|
temperature = Math.max(temperature, 0.01);
|
||||||
const chatAPI = getAIChatApi(userOpenaiAccount);
|
const chatAPI = getAIChatApi(user.openaiAccount);
|
||||||
|
|
||||||
const response = await chatAPI.createChatCompletion(
|
const response = await chatAPI.createChatCompletion(
|
||||||
{
|
{
|
||||||
@ -128,7 +129,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
{
|
{
|
||||||
timeout: 480000,
|
timeout: 480000,
|
||||||
responseType: stream ? 'stream' : 'json',
|
responseType: stream ? 'stream' : 'json',
|
||||||
...axiosConfig(userOpenaiAccount)
|
...axiosConfig(user.openaiAccount)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -179,7 +180,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
[TaskResponseKeyEnum.responseData]: {
|
[TaskResponseKeyEnum.responseData]: {
|
||||||
moduleType: FlowModuleTypeEnum.chatNode,
|
moduleType: FlowModuleTypeEnum.chatNode,
|
||||||
moduleName,
|
moduleName,
|
||||||
price: userOpenaiAccount?.key ? 0 : countModelPrice({ model, tokens: totalTokens }),
|
price: user.openaiAccount?.key ? 0 : countModelPrice({ model, tokens: totalTokens }),
|
||||||
model: modelConstantsData.name,
|
model: modelConstantsData.name,
|
||||||
tokens: totalTokens,
|
tokens: totalTokens,
|
||||||
question: userChatInput,
|
question: userChatInput,
|
||||||
@ -187,6 +188,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
quoteList: filterQuoteQA,
|
quoteList: filterQuoteQA,
|
||||||
historyPreview: getHistoryPreview(completeMessages)
|
historyPreview: getHistoryPreview(completeMessages)
|
||||||
},
|
},
|
||||||
|
[TaskResponseKeyEnum.history]: completeMessages,
|
||||||
finish: true
|
finish: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,5 +4,6 @@ export * from './chat/oneapi';
|
|||||||
export * from './kb/search';
|
export * from './kb/search';
|
||||||
export * from './tools/answer';
|
export * from './tools/answer';
|
||||||
export * from './tools/http';
|
export * from './tools/http';
|
||||||
|
export * from './tools/runApp';
|
||||||
export * from './agent/classifyQuestion';
|
export * from './agent/classifyQuestion';
|
||||||
export * from './agent/extract';
|
export * from './agent/extract';
|
||||||
|
|||||||
@ -6,7 +6,6 @@ export type AnswerProps = ModuleDispatchProps<{
|
|||||||
text: string;
|
text: string;
|
||||||
}>;
|
}>;
|
||||||
export type AnswerResponse = {
|
export type AnswerResponse = {
|
||||||
[TaskResponseKeyEnum.answerText]: string;
|
|
||||||
finish: boolean;
|
finish: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,7 +28,6 @@ export const dispatchAnswer = (props: Record<string, any>): AnswerResponse => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[TaskResponseKeyEnum.answerText]: text,
|
|
||||||
finish: true
|
finish: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
80
projects/app/src/service/moduleDispatch/tools/runApp.ts
Normal file
80
projects/app/src/service/moduleDispatch/tools/runApp.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { ChatHistoryItemResType, ChatItemType } from '@/types/chat';
|
||||||
|
import type { ModuleDispatchProps } from '@/types/core/chat/type';
|
||||||
|
import { SelectAppItemType } from '@/types/core/app/flow';
|
||||||
|
import { dispatchModules } from '@/pages/api/v1/chat/completions';
|
||||||
|
import { App } from '@/service/mongo';
|
||||||
|
import { responseWrite } from '@/service/common/stream';
|
||||||
|
import { ChatRoleEnum, TaskResponseKeyEnum, sseResponseEventEnum } from '@/constants/chat';
|
||||||
|
import { textAdaptGptResponse } from '@/utils/adapt';
|
||||||
|
|
||||||
|
type Props = ModuleDispatchProps<{
|
||||||
|
userChatInput: string;
|
||||||
|
history?: ChatItemType[];
|
||||||
|
app: SelectAppItemType;
|
||||||
|
}>;
|
||||||
|
type Response = {
|
||||||
|
finish: boolean;
|
||||||
|
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType[];
|
||||||
|
[TaskResponseKeyEnum.answerText]: string;
|
||||||
|
[TaskResponseKeyEnum.history]: ChatItemType[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const dispatchAppRequest = async (props: Record<string, any>): Promise<Response> => {
|
||||||
|
const {
|
||||||
|
res,
|
||||||
|
variables,
|
||||||
|
user,
|
||||||
|
stream,
|
||||||
|
detail,
|
||||||
|
inputs: { userChatInput, history = [], app }
|
||||||
|
} = props as Props;
|
||||||
|
|
||||||
|
if (!userChatInput) {
|
||||||
|
return Promise.reject('Input is empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
const appData = await App.findById(app.id);
|
||||||
|
|
||||||
|
if (!appData) {
|
||||||
|
return Promise.reject('App not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
responseWrite({
|
||||||
|
res,
|
||||||
|
event: detail ? sseResponseEventEnum.answer : undefined,
|
||||||
|
data: textAdaptGptResponse({
|
||||||
|
text: '\n'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const { responseData, answerText } = await dispatchModules({
|
||||||
|
res,
|
||||||
|
modules: appData.modules,
|
||||||
|
user,
|
||||||
|
variables,
|
||||||
|
params: {
|
||||||
|
history,
|
||||||
|
userChatInput
|
||||||
|
},
|
||||||
|
stream,
|
||||||
|
detail
|
||||||
|
});
|
||||||
|
|
||||||
|
const completeMessages = history.concat([
|
||||||
|
{
|
||||||
|
obj: ChatRoleEnum.Human,
|
||||||
|
value: userChatInput
|
||||||
|
},
|
||||||
|
{
|
||||||
|
obj: ChatRoleEnum.AI,
|
||||||
|
value: answerText
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
finish: true,
|
||||||
|
responseData,
|
||||||
|
[TaskResponseKeyEnum.answerText]: answerText,
|
||||||
|
[TaskResponseKeyEnum.history]: completeMessages
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -102,8 +102,23 @@ export async function authOutLinkLimit({
|
|||||||
await authShareStart({ authToken, tokenUrl: outLink.limit.hookUrl, question });
|
await authShareStart({ authToken, tokenUrl: outLink.limit.hookUrl, question });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function authOutLinkId({ id }: { id: string }) {
|
||||||
|
const outLink = await OutLink.findOne({
|
||||||
|
shareId: id
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!outLink) {
|
||||||
|
return Promise.reject('分享链接无效');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
userId: String(outLink.userId)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
type TokenAuthResponseType = {
|
type TokenAuthResponseType = {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
|
msg?: string;
|
||||||
message?: string;
|
message?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,7 +134,7 @@ export const authShareChatInit = async (authToken?: string, tokenUrl?: string) =
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (data?.success !== true) {
|
if (data?.success !== true) {
|
||||||
return Promise.reject(data?.message || '身份校验失败');
|
return Promise.reject(data?.message || data?.msg || '身份校验失败');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject('身份校验失败');
|
return Promise.reject('身份校验失败');
|
||||||
@ -148,7 +163,7 @@ export const authShareStart = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (data?.success !== true) {
|
if (data?.success !== true) {
|
||||||
return Promise.reject(data?.message || '身份校验失败');
|
return Promise.reject(data?.message || data?.msg || '身份校验失败');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject('身份校验失败');
|
return Promise.reject('身份校验失败');
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import type { NextApiRequest } from 'next';
|
import type { NextApiRequest } from 'next';
|
||||||
import Cookie from 'cookie';
|
import Cookie from 'cookie';
|
||||||
import { App, OpenApi, User, KB } from '../mongo';
|
import { App, User, KB } from '../mongo';
|
||||||
import type { AppSchema, UserModelSchema } from '@/types/mongoSchema';
|
import type { AppSchema, UserModelSchema } from '@/types/mongoSchema';
|
||||||
import { ERROR_ENUM } from '../errorCode';
|
import { ERROR_ENUM } from '../errorCode';
|
||||||
import { authJWT } from './tools';
|
import { authJWT } from './tools';
|
||||||
import { authOpenApiKey } from '../support/openapi/auth';
|
import { authOpenApiKey } from '../support/openapi/auth';
|
||||||
|
import { authOutLinkId } from '../support/outLink/auth';
|
||||||
|
|
||||||
export enum AuthUserTypeEnum {
|
export enum AuthUserTypeEnum {
|
||||||
token = 'token',
|
token = 'token',
|
||||||
root = 'root',
|
root = 'root',
|
||||||
apikey = 'apikey'
|
apikey = 'apikey',
|
||||||
|
outLink = 'outLink'
|
||||||
}
|
}
|
||||||
|
|
||||||
/* auth balance */
|
/* auth balance */
|
||||||
@ -34,13 +36,15 @@ export const authUser = async ({
|
|||||||
authToken = false,
|
authToken = false,
|
||||||
authRoot = false,
|
authRoot = false,
|
||||||
authApiKey = false,
|
authApiKey = false,
|
||||||
authBalance = false
|
authBalance = false,
|
||||||
|
authOutLink
|
||||||
}: {
|
}: {
|
||||||
req: NextApiRequest;
|
req: NextApiRequest;
|
||||||
authToken?: boolean;
|
authToken?: boolean;
|
||||||
authRoot?: boolean;
|
authRoot?: boolean;
|
||||||
authApiKey?: boolean;
|
authApiKey?: boolean;
|
||||||
authBalance?: boolean;
|
authBalance?: boolean;
|
||||||
|
authOutLink?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const authCookieToken = async (cookie?: string, token?: string): Promise<string> => {
|
const authCookieToken = async (cookie?: string, token?: string): Promise<string> => {
|
||||||
// 获取 cookie
|
// 获取 cookie
|
||||||
@ -107,13 +111,18 @@ export const authUser = async ({
|
|||||||
userid?: string;
|
userid?: string;
|
||||||
authorization?: string;
|
authorization?: string;
|
||||||
};
|
};
|
||||||
|
const { shareId } = (req?.body || {}) as { shareId?: string };
|
||||||
|
|
||||||
let uid = '';
|
let uid = '';
|
||||||
let appId = '';
|
let appId = '';
|
||||||
let openApiKey = apikey;
|
let openApiKey = apikey;
|
||||||
let authType: `${AuthUserTypeEnum}` = AuthUserTypeEnum.token;
|
let authType: `${AuthUserTypeEnum}` = AuthUserTypeEnum.token;
|
||||||
|
|
||||||
if (authToken && (cookie || token)) {
|
if (authOutLink && shareId) {
|
||||||
|
const res = await authOutLinkId({ id: shareId });
|
||||||
|
uid = res.userId;
|
||||||
|
authType = AuthUserTypeEnum.outLink;
|
||||||
|
} else if (authToken && (cookie || token)) {
|
||||||
// user token(from fastgpt web)
|
// user token(from fastgpt web)
|
||||||
uid = await authCookieToken(cookie, token);
|
uid = await authCookieToken(cookie, token);
|
||||||
authType = AuthUserTypeEnum.token;
|
authType = AuthUserTypeEnum.token;
|
||||||
|
|||||||
6
projects/app/src/types/core/app/flow.d.ts
vendored
6
projects/app/src/types/core/app/flow.d.ts
vendored
@ -60,3 +60,9 @@ export type FlowModuleTemplateType = {
|
|||||||
export type FlowModuleItemType = FlowModuleTemplateType & {
|
export type FlowModuleItemType = FlowModuleTemplateType & {
|
||||||
moduleId: string;
|
moduleId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SelectAppItemType = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
logo: string;
|
||||||
|
};
|
||||||
|
|||||||
4
projects/app/src/types/core/chat/type.d.ts
vendored
4
projects/app/src/types/core/chat/type.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
import type { ChatCompletionRequestMessage } from '@fastgpt/core/aiApi/type';
|
import type { ChatCompletionRequestMessage } from '@fastgpt/core/ai/type';
|
||||||
import type { NextApiResponse } from 'next';
|
import type { NextApiResponse } from 'next';
|
||||||
import { RunningModuleItemType } from '@/types/app';
|
import { RunningModuleItemType } from '@/types/app';
|
||||||
import { UserModelSchema } from '@/types/mongoSchema';
|
import { UserModelSchema } from '@/types/mongoSchema';
|
||||||
@ -13,6 +13,6 @@ export type ModuleDispatchProps<T> = {
|
|||||||
detail: boolean;
|
detail: boolean;
|
||||||
variables: Record<string, any>;
|
variables: Record<string, any>;
|
||||||
outputs: RunningModuleItemType['outputs'];
|
outputs: RunningModuleItemType['outputs'];
|
||||||
userOpenaiAccount?: UserModelSchema['openaiAccount'];
|
user: UserModelSchema;
|
||||||
inputs: T;
|
inputs: T;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { formatPrice } from '@fastgpt/common/bill/index';
|
|||||||
import type { BillSchema } from '@/types/common/bill';
|
import type { BillSchema } from '@/types/common/bill';
|
||||||
import type { UserBillType } from '@/types/user';
|
import type { UserBillType } from '@/types/user';
|
||||||
import { ChatItemType } from '@/types/chat';
|
import { ChatItemType } from '@/types/chat';
|
||||||
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/core/aiApi/constant';
|
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/core/ai/constant';
|
||||||
import { ChatRoleEnum } from '@/constants/chat';
|
import { ChatRoleEnum } from '@/constants/chat';
|
||||||
import type { MessageItemType } from '@/types/core/chat/type';
|
import type { MessageItemType } from '@/types/core/chat/type';
|
||||||
import type { AppModuleItemType } from '@/types/app';
|
import type { AppModuleItemType } from '@/types/app';
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import type { ChatItemType } from '@/types/chat';
|
import type { ChatItemType } from '@/types/chat';
|
||||||
import { ChatRoleEnum } from '@/constants/chat';
|
import { ChatRoleEnum } from '@/constants/chat';
|
||||||
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/core/aiApi/constant';
|
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/core/ai/constant';
|
||||||
import type { MessageItemType } from '@/types/core/chat/type';
|
import type { MessageItemType } from '@/types/core/chat/type';
|
||||||
|
|
||||||
const chat2Message = {
|
const chat2Message = {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
import { ChatItemType } from '@/types/chat';
|
import { ChatItemType } from '@/types/chat';
|
||||||
import { Tiktoken } from 'js-tiktoken/lite';
|
import { Tiktoken } from 'js-tiktoken/lite';
|
||||||
import { adaptChat2GptMessages } from '../adapt/message';
|
import { adaptChat2GptMessages } from '../adapt/message';
|
||||||
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/core/aiApi/constant';
|
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/core/ai/constant';
|
||||||
import encodingJson from './cl100k_base.json';
|
import encodingJson from './cl100k_base.json';
|
||||||
|
|
||||||
/* init tikToken obj */
|
/* init tikToken obj */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user