Commit ab57bfcc by Archer Committed by GitHub

perf: completions api.fix: new chat question guide (#361)

parent 11848b8f
...@@ -39,7 +39,7 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b ...@@ -39,7 +39,7 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b
- [x] 文本内容提取成结构化数据 - [x] 文本内容提取成结构化数据
- [x] HTTP 扩展 - [x] HTTP 扩展
- [ ] 嵌入 Laf,实现在线编写 HTTP 模块 - [ ] 嵌入 Laf,实现在线编写 HTTP 模块
- [ ] 连续对话引导 - [x] 对话下一步指引
- [ ] 对话多路线选择 - [ ] 对话多路线选择
- [x] 源文件引用追踪 - [x] 源文件引用追踪
- [ ] 自定义文件阅读器 - [ ] 自定义文件阅读器
...@@ -55,7 +55,7 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b ...@@ -55,7 +55,7 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b
- [x] 知识库单点搜索测试 - [x] 知识库单点搜索测试
- [x] 对话时反馈引用并可修改与删除 - [x] 对话时反馈引用并可修改与删除
- [x] 完整上下文呈现 - [x] 完整上下文呈现
- [ ] 完整模块中间值呈现 - [x] 完整模块中间值呈现
4. OpenAPI 4. OpenAPI
- [x] completions 接口(对齐 GPT 接口) - [x] completions 接口(对齐 GPT 接口)
- [ ] 知识库 CRUD - [ ] 知识库 CRUD
......
...@@ -46,7 +46,7 @@ FastGPT çš„ API Key 有 2 类,一类是全局通用的 key;一类是æºå¸¦äº ...@@ -46,7 +46,7 @@ FastGPT çš„ API Key 有 2 类,一类是全局通用的 key;一类是æºå¸¦äº
**请求示例:** **请求示例:**
```bash ```bash
curl --location --request POST 'https://fastgpt.run/api/openapi/v1/chat/completions' \ curl --location --request POST 'https://fastgpt.run/api/v1/chat/completions' \
--header 'Authorization: Bearer apikey' \ --header 'Authorization: Bearer apikey' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
......
...@@ -26,7 +26,7 @@ weight: 312 ...@@ -26,7 +26,7 @@ weight: 312
## 3. 创建 docker-compose.yml 文件 ## 3. 创建 docker-compose.yml 文件
只需要修改 `OPEN_AI_API_KEY``OPEN_AI_API_BASE` 两个环境变量即可。其中 `OPEN_AI_API_KEY` 为第一步获取的秘钥,`OPEN_AI_API_BASE` 为 FastGPT 的 OpenAPI 地址,例如:`https://fastgpt.run/api/openapi/v1` 只需要修改 `OPEN_AI_API_KEY``OPEN_AI_API_BASE` 两个环境变量即可。其中 `OPEN_AI_API_KEY` 为第一步获取的秘钥,`OPEN_AI_API_BASE` 为 FastGPT 的 OpenAPI 地址,例如:`https://fastgpt.run/api/v1`
随便找一个目录,创建一个 docker-compose.yml 文件,将下面的代码复制进去。 随便找一个目录,创建一个 docker-compose.yml 文件,将下面的代码复制进去。
...@@ -40,7 +40,7 @@ services: ...@@ -40,7 +40,7 @@ services:
- seccomp:unconfined - seccomp:unconfined
environment: environment:
OPEN_AI_API_KEY: 'fastgpt-z51pkjqm9nrk03a1rx2funoy' OPEN_AI_API_KEY: 'fastgpt-z51pkjqm9nrk03a1rx2funoy'
OPEN_AI_API_BASE: 'https://fastgpt.run/api/openapi/v1' OPEN_AI_API_BASE: 'https://fastgpt.run/api/v1'
MODEL: 'gpt-3.5-turbo' MODEL: 'gpt-3.5-turbo'
CHANNEL_TYPE: 'wx' CHANNEL_TYPE: 'wx'
PROXY: '' PROXY: ''
......
...@@ -25,7 +25,7 @@ Tips: 安全起见,你可以设置一个额度或者过期时间,放置 key ...@@ -25,7 +25,7 @@ Tips: 安全起见,你可以设置一个额度或者过期时间,放置 key
## 替换三方应用的变量 ## 替换三方应用的变量
```bash ```bash
OPENAI_API_BASE_URL: https://fastgpt.run/api/openapi (改成自己部署的域名) OPENAI_API_BASE_URL: https://fastgpt.run/api (改成自己部署的域名)
OPENAI_API_KEY = 上一步获取到的秘钥 OPENAI_API_KEY = 上一步获取到的秘钥
``` ```
......
...@@ -12,7 +12,7 @@ interface StreamFetchProps { ...@@ -12,7 +12,7 @@ interface StreamFetchProps {
abortSignal: AbortController; abortSignal: AbortController;
} }
export const streamFetch = ({ export const streamFetch = ({
url = '/api/openapi/v1/chat/completions', url = '/api/v1/chat/completions',
data, data,
onMessage, onMessage,
abortSignal abortSignal
......
...@@ -27,7 +27,7 @@ import { useMarkdown } from '@/hooks/useMarkdown'; ...@@ -27,7 +27,7 @@ import { useMarkdown } from '@/hooks/useMarkdown';
import { AppModuleItemType, VariableItemType } from '@/types/app'; import { AppModuleItemType, VariableItemType } 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 { MessageItemType } from '@/pages/api/openapi/v1/chat/completions'; import type { MessageItemType } from '@/types/core/chat/type';
import { fileDownload } from '@/utils/web/file'; import { fileDownload } from '@/utils/web/file';
import { htmlTemplate } from '@/constants/common'; import { htmlTemplate } from '@/constants/common';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
...@@ -158,6 +158,7 @@ const ChatBox = ( ...@@ -158,6 +158,7 @@ const ChatBox = (
onStartChat?: (e: StartChatFnProps) => Promise<{ onStartChat?: (e: StartChatFnProps) => Promise<{
responseText: string; responseText: string;
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType[]; [TaskResponseKeyEnum.responseData]: ChatHistoryItemResType[];
isNewChat?: boolean;
}>; }>;
onDelMessage?: (e: { contentId?: string; index: number }) => void; onDelMessage?: (e: { contentId?: string; index: number }) => void;
}, },
...@@ -173,6 +174,7 @@ const ChatBox = ( ...@@ -173,6 +174,7 @@ const ChatBox = (
const TextareaDom = useRef<HTMLTextAreaElement>(null); const TextareaDom = useRef<HTMLTextAreaElement>(null);
const chatController = useRef(new AbortController()); const chatController = useRef(new AbortController());
const questionGuideController = useRef(new AbortController()); const questionGuideController = useRef(new AbortController());
const isNewChatReplace = useRef(false);
const [refresh, setRefresh] = useState(false); const [refresh, setRefresh] = useState(false);
const [variables, setVariables] = useState<Record<string, any>>({}); // settings variable const [variables, setVariables] = useState<Record<string, any>>({}); // settings variable
...@@ -381,7 +383,11 @@ const ChatBox = ( ...@@ -381,7 +383,11 @@ const ChatBox = (
const messages = adaptChat2GptMessages({ messages: newChatList, reserveId: true }); const messages = adaptChat2GptMessages({ messages: newChatList, reserveId: true });
const { responseData, responseText } = await onStartChat({ const {
responseData,
responseText,
isNewChat = false
} = await onStartChat({
chatList: newChatList, chatList: newChatList,
messages, messages,
controller: abortSignal, controller: abortSignal,
...@@ -389,6 +395,8 @@ const ChatBox = ( ...@@ -389,6 +395,8 @@ const ChatBox = (
variables variables
}); });
isNewChatReplace.current = isNewChat;
// set finish status // set finish status
setChatHistory((state) => setChatHistory((state) =>
state.map((item, index) => { state.map((item, index) => {
...@@ -542,9 +550,12 @@ const ChatBox = ( ...@@ -542,9 +550,12 @@ const ChatBox = (
// page change and abort request // page change and abort request
useEffect(() => { useEffect(() => {
isNewChatReplace.current = false;
return () => { return () => {
chatController.current?.abort('leave'); chatController.current?.abort('leave');
questionGuideController.current?.abort('leave'); if (!isNewChatReplace.current) {
questionGuideController.current?.abort('leave');
}
// close voice // close voice
cancelBroadcast(); cancelBroadcast();
}; };
......
...@@ -171,11 +171,10 @@ ...@@ -171,11 +171,10 @@
.markdown ol li > *:first-child { .markdown ol li > *:first-child {
margin-top: 0; margin-top: 0;
} }
.markdown ul ul, .markdown ul,
.markdown ul ol, .markdown ol {
.markdown ol ol,
.markdown ol ul {
margin-bottom: 0; margin-bottom: 0;
padding-left: 14px;
} }
.markdown dl { .markdown dl {
padding: 0; padding: 0;
......
...@@ -5,7 +5,7 @@ import { sseErrRes } from '@/service/response'; ...@@ -5,7 +5,7 @@ import { sseErrRes } from '@/service/response';
import { sseResponseEventEnum } from '@/constants/chat'; import { sseResponseEventEnum } from '@/constants/chat';
import { sseResponse } from '@/service/utils/tools'; import { sseResponse } from '@/service/utils/tools';
import { AppModuleItemType } from '@/types/app'; import { AppModuleItemType } from '@/types/app';
import { dispatchModules } from '../openapi/v1/chat/completions'; import { dispatchModules } from '@/pages/api/v1/chat/completions';
import { pushChatBill } from '@/service/common/bill/push'; import { pushChatBill } from '@/service/common/bill/push';
import { BillSourceEnum } from '@/constants/user'; import { BillSourceEnum } from '@/constants/user';
import { ChatItemType } from '@/types/chat'; import { ChatItemType } from '@/types/chat';
......
...@@ -113,7 +113,7 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => { ...@@ -113,7 +113,7 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
history: ChatBoxRef.current?.getChatHistory() || state.history history: ChatBoxRef.current?.getChatHistory() || state.history
})); }));
return { responseText, responseData }; return { responseText, responseData, isNewChat: forbidRefresh.current };
}, },
[appId, chatId, history, router, setChatData, updateHistory] [appId, chatId, history, router, setChatData, updateHistory]
); );
......
...@@ -106,7 +106,7 @@ const OutLink = ({ ...@@ -106,7 +106,7 @@ const OutLink = ({
'*' '*'
); );
return { responseText, responseData }; return { responseText, responseData, isNewChat: forbidRefresh.current };
}, },
[authToken, chatId, router, saveChatResponse, shareId] [authToken, chatId, router, saveChatResponse, shareId]
); );
......
import type { ChatCompletionRequestMessage } from '@fastgpt/core/aiApi/type';
export type MessageItemType = ChatCompletionRequestMessage & { dataId?: string };
...@@ -4,7 +4,7 @@ import type { UserBillType } from '@/types/user'; ...@@ -4,7 +4,7 @@ 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/aiApi/constant';
import { ChatRoleEnum } from '@/constants/chat'; import { ChatRoleEnum } from '@/constants/chat';
import type { MessageItemType } from '@/pages/api/openapi/v1/chat/completions'; import type { MessageItemType } from '@/types/core/chat/type';
import type { AppModuleItemType } from '@/types/app'; import type { AppModuleItemType } from '@/types/app';
import type { FlowModuleItemType } from '@/types/flow'; import type { FlowModuleItemType } from '@/types/flow';
import type { Edge, Node } from 'reactflow'; import type { Edge, Node } from 'reactflow';
......
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/aiApi/constant';
import type { MessageItemType } from '@/pages/api/openapi/v1/chat/completions'; import type { MessageItemType } from '@/types/core/chat/type';
const chat2Message = { const chat2Message = {
[ChatRoleEnum.AI]: ChatCompletionRequestMessageRoleEnum.Assistant, [ChatRoleEnum.AI]: ChatCompletionRequestMessageRoleEnum.Assistant,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment