feat: 可以手动停止AI的输出(左下角按钮)
This commit is contained in:
parent
1eb3c596f3
commit
a72329d4a2
|
@ -9,6 +9,7 @@
|
||||||
"生成轮数": "Generation Rounds",
|
"生成轮数": "Generation Rounds",
|
||||||
"时间范围": "Range of literature release dates, from this time to this year",
|
"时间范围": "Range of literature release dates, from this time to this year",
|
||||||
"更新文中的上标,使得数字顺序排列": "Update the superscript in the text to make the numbers in order",
|
"更新文中的上标,使得数字顺序排列": "Update the superscript in the text to make the numbers in order",
|
||||||
|
"停止生成": "Stop Generation",
|
||||||
"+ Add Paper": "+ Add Paper",
|
"+ Add Paper": "+ Add Paper",
|
||||||
"Buy VIP TO UNLOCK Cloud Sync and Edit Mutiple Papers Simultaneously": "Buy VIP TO UNLOCK Cloud Sync and Edit Mutiple Papers Simultaneously",
|
"Buy VIP TO UNLOCK Cloud Sync and Edit Mutiple Papers Simultaneously": "Buy VIP TO UNLOCK Cloud Sync and Edit Mutiple Papers Simultaneously",
|
||||||
"Paper Management": "Paper Management",
|
"Paper Management": "Paper Management",
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"生成轮数": "生成轮数",
|
"生成轮数": "生成轮数",
|
||||||
"时间范围": "文献发布日期范围,从这个时间到今年",
|
"时间范围": "文献发布日期范围,从这个时间到今年",
|
||||||
"更新文中的上标,使得数字顺序排列": "更新文中的上标,使得数字顺序排列",
|
"更新文中的上标,使得数字顺序排列": "更新文中的上标,使得数字顺序排列",
|
||||||
|
"停止生成": "停止生成",
|
||||||
"+ Add Paper": "+ 添加新论文(会直接替换编辑器里的内容)",
|
"+ Add Paper": "+ 添加新论文(会直接替换编辑器里的内容)",
|
||||||
"Buy VIP TO UNLOCK Cloud Sync and Edit Mutiple Papers Simultaneously": "购买VIP解锁云同步和同时编辑多篇论文",
|
"Buy VIP TO UNLOCK Cloud Sync and Edit Mutiple Papers Simultaneously": "购买VIP解锁云同步和同时编辑多篇论文",
|
||||||
"Paper Management": "论文管理",
|
"Paper Management": "论文管理",
|
||||||
|
|
|
@ -116,11 +116,12 @@ const QEditor = ({ lng }) => {
|
||||||
//选择时间范围
|
//选择时间范围
|
||||||
const [timeRange, setTimeRange] = useLocalStorage("时间范围", "2019");
|
const [timeRange, setTimeRange] = useLocalStorage("时间范围", "2019");
|
||||||
const [generateNumber, setGenerateNumber] = useState(0); //当前任务的进行数
|
const [generateNumber, setGenerateNumber] = useState(0); //当前任务的进行数
|
||||||
const [openProgressBar, setOpenProgressBar] = useState(false);
|
const [openProgressBar, setOpenProgressBar] = useState(false); //设置进度条是否打开
|
||||||
const [showAnnouncement, setShowAnnouncement] = useLocalStorage(
|
const [showAnnouncement, setShowAnnouncement] = useLocalStorage(
|
||||||
"显示公告",
|
"显示公告",
|
||||||
true
|
true
|
||||||
); // 是否显示公告
|
); // 是否显示公告
|
||||||
|
const [controller, setController] = useState<AbortController | null>(null); // 创建 AbortController 的状态
|
||||||
|
|
||||||
//redux
|
//redux
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
@ -287,6 +288,11 @@ const QEditor = ({ lng }) => {
|
||||||
};
|
};
|
||||||
// 处理AI写作
|
// 处理AI写作
|
||||||
const handleAIWrite = async () => {
|
const handleAIWrite = async () => {
|
||||||
|
try {
|
||||||
|
setOpenProgressBar(true); //开启进度条
|
||||||
|
// 创建一个新的 AbortController 实例
|
||||||
|
const newController = new AbortController();
|
||||||
|
setController(newController);
|
||||||
quill!.setSelection(cursorPosition!, 0); // 将光标移动到原来的位置
|
quill!.setSelection(cursorPosition!, 0); // 将光标移动到原来的位置
|
||||||
|
|
||||||
const prompt = "请帮助用户完成论文写作,使用用户所说的语言完成";
|
const prompt = "请帮助用户完成论文写作,使用用户所说的语言完成";
|
||||||
|
@ -297,7 +303,9 @@ const QEditor = ({ lng }) => {
|
||||||
apiKey,
|
apiKey,
|
||||||
upsreamUrl,
|
upsreamUrl,
|
||||||
prompt,
|
prompt,
|
||||||
cursorPosition!
|
cursorPosition!,
|
||||||
|
true,
|
||||||
|
newController.signal // 传递 AbortSignal
|
||||||
);
|
);
|
||||||
// 清空input内容
|
// 清空input内容
|
||||||
setUserInput("");
|
setUserInput("");
|
||||||
|
@ -309,10 +317,23 @@ const QEditor = ({ lng }) => {
|
||||||
autoClose: 2000,
|
autoClose: 2000,
|
||||||
pauseOnHover: true,
|
pauseOnHover: true,
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(`AI写作出现错误: ${error}`, {
|
||||||
|
position: "top-center",
|
||||||
|
autoClose: 3000,
|
||||||
|
pauseOnHover: true,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setOpenProgressBar(false); //关闭进度条
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理paper2AI
|
// 处理paper2AI
|
||||||
async function paper2AI(topic: string) {
|
async function paper2AI(topic: string) {
|
||||||
|
try {
|
||||||
|
// 创建一个新的 AbortController 实例
|
||||||
|
const newController = new AbortController();
|
||||||
|
setController(newController);
|
||||||
quill!.setSelection(cursorPosition!, 0); // 将光标移动到原来的位置
|
quill!.setSelection(cursorPosition!, 0); // 将光标移动到原来的位置
|
||||||
let offset = -1;
|
let offset = -1;
|
||||||
if (generatedPaperNumber != 1) offset = 0; //如果生成的数量不为1,则从0开始
|
if (generatedPaperNumber != 1) offset = 0; //如果生成的数量不为1,则从0开始
|
||||||
|
@ -338,7 +359,8 @@ const QEditor = ({ lng }) => {
|
||||||
upsreamUrl,
|
upsreamUrl,
|
||||||
prompt,
|
prompt,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
newController.signal // 传递 AbortSignal
|
||||||
);
|
);
|
||||||
console.log("topic in AI before removeSpecialCharacters", topic);
|
console.log("topic in AI before removeSpecialCharacters", topic);
|
||||||
topic = removeSpecialCharacters(topic);
|
topic = removeSpecialCharacters(topic);
|
||||||
|
@ -362,7 +384,8 @@ const QEditor = ({ lng }) => {
|
||||||
apiKey,
|
apiKey,
|
||||||
upsreamUrl,
|
upsreamUrl,
|
||||||
selectedModel!,
|
selectedModel!,
|
||||||
topic
|
topic,
|
||||||
|
newController.signal
|
||||||
);
|
);
|
||||||
rawData = relevantPapers;
|
rawData = relevantPapers;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +417,8 @@ const QEditor = ({ lng }) => {
|
||||||
apiKey,
|
apiKey,
|
||||||
upsreamUrl,
|
upsreamUrl,
|
||||||
selectedModel!,
|
selectedModel!,
|
||||||
topic
|
topic,
|
||||||
|
newController.signal
|
||||||
);
|
);
|
||||||
rawData = relevantPapers;
|
rawData = relevantPapers;
|
||||||
}
|
}
|
||||||
|
@ -431,7 +455,8 @@ const QEditor = ({ lng }) => {
|
||||||
apiKey,
|
apiKey,
|
||||||
upsreamUrl,
|
upsreamUrl,
|
||||||
selectedModel!,
|
selectedModel!,
|
||||||
topic
|
topic,
|
||||||
|
newController.signal
|
||||||
);
|
);
|
||||||
rawData = relevantPapers;
|
rawData = relevantPapers;
|
||||||
}
|
}
|
||||||
|
@ -475,7 +500,9 @@ const QEditor = ({ lng }) => {
|
||||||
apiKey,
|
apiKey,
|
||||||
upsreamUrl,
|
upsreamUrl,
|
||||||
systemPrompt,
|
systemPrompt,
|
||||||
cursorPosition!
|
cursorPosition!,
|
||||||
|
true,
|
||||||
|
newController.signal // 传递 AbortSignal
|
||||||
);
|
);
|
||||||
setUserInput("");
|
setUserInput("");
|
||||||
// 重新获取更新后的内容并更新 Redux store
|
// 重新获取更新后的内容并更新 Redux store
|
||||||
|
@ -517,10 +544,24 @@ const QEditor = ({ lng }) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(`Paper2AI出现错误: ${error}`, {
|
||||||
|
position: "top-center",
|
||||||
|
autoClose: 3000,
|
||||||
|
pauseOnHover: true,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
setOpenProgressBar(false);
|
setOpenProgressBar(false);
|
||||||
setGenerateNumber(0); //总的已经生成的数量
|
setGenerateNumber(0); //总的已经生成的数量
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleStop = () => {
|
||||||
|
if (controller) {
|
||||||
|
controller.abort(); // 取消请求
|
||||||
|
setController(null); // 重置 controller 状态
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col ">
|
<div className="flex flex-col ">
|
||||||
<div id="Qtoolbar" className="space-y-2 flex justify-between">
|
<div id="Qtoolbar" className="space-y-2 flex justify-between">
|
||||||
|
@ -601,6 +642,16 @@ const QEditor = ({ lng }) => {
|
||||||
<ReferenceList editor={quill} lng={lng} />
|
<ReferenceList editor={quill} lng={lng} />
|
||||||
<ExportDocx editor={quill} />
|
<ExportDocx editor={quill} />
|
||||||
</div>
|
</div>
|
||||||
|
{/* 停止生成的按钮只有在开始对话之后才会出现 */}
|
||||||
|
{openProgressBar ? (
|
||||||
|
<button
|
||||||
|
onClick={handleStop}
|
||||||
|
className="fixed bottom-4 left-4 bg-red-500 hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-opacity-50 active:bg-red-700 text-white font-bold py-2 px-4 rounded transition ease-in-out duration-150 shadow-lg hover:shadow-xl"
|
||||||
|
>
|
||||||
|
{t("停止生成")}
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
convertToSuperscript,
|
convertToSuperscript,
|
||||||
deleteSameBracketNumber,
|
deleteSameBracketNumber,
|
||||||
} from "@/utils/others/quillutils";
|
} from "@/utils/others/quillutils";
|
||||||
|
import { faSignal } from "@fortawesome/free-solid-svg-icons";
|
||||||
//redux不能在普通函数使用
|
//redux不能在普通函数使用
|
||||||
|
|
||||||
interface ChatData {
|
interface ChatData {
|
||||||
|
@ -29,7 +30,8 @@ const sendMessageToOpenAI = async (
|
||||||
upsreamUrl: string,
|
upsreamUrl: string,
|
||||||
prompt: string,
|
prompt: string,
|
||||||
cursorPosition: number | null,
|
cursorPosition: number | null,
|
||||||
useEditorFlag = true // 新增的标志,用于决定操作
|
useEditorFlag = true, // 新增的标志,用于决定操作
|
||||||
|
signal: AbortSignal
|
||||||
) => {
|
) => {
|
||||||
//识别应该使用的模型
|
//识别应该使用的模型
|
||||||
let model = selectedModel;
|
let model = selectedModel;
|
||||||
|
@ -37,6 +39,7 @@ const sendMessageToOpenAI = async (
|
||||||
// 设置API请求参数
|
// 设置API请求参数
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
signal: signal,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
// "Upstream-Url": upsreamUrl,
|
// "Upstream-Url": upsreamUrl,
|
||||||
|
@ -106,7 +109,12 @@ const sendMessageToOpenAI = async (
|
||||||
const content = data.choices[0].message.content;
|
const content = data.choices[0].message.content;
|
||||||
return content; // 或根据需要处理并返回数据
|
return content; // 或根据需要处理并返回数据
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
|
if (error.name === "AbortError") {
|
||||||
|
console.log("Fetch operation was aborted");
|
||||||
|
//这里不用产生报错因为是手动停止
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.error("Error:", error);
|
console.error("Error:", error);
|
||||||
// 如果有响应,返回响应的原始内容
|
// 如果有响应,返回响应的原始内容
|
||||||
if (response) {
|
if (response) {
|
||||||
|
|
|
@ -74,7 +74,8 @@ export async function evaluateTopicMatch(
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
upsreamUrl: string,
|
upsreamUrl: string,
|
||||||
selectedModel: string,
|
selectedModel: string,
|
||||||
topic: string
|
topic: string,
|
||||||
|
signal: AbortSignal
|
||||||
): Promise<{ relevantPapers: string[]; nonRelevantPapers: string[] }> {
|
): Promise<{ relevantPapers: string[]; nonRelevantPapers: string[] }> {
|
||||||
const prompt =
|
const prompt =
|
||||||
"请判断文献是否跟用户输入的主题相关,只需要返回true或false的数组";
|
"请判断文献是否跟用户输入的主题相关,只需要返回true或false的数组";
|
||||||
|
@ -117,7 +118,8 @@ export async function evaluateTopicMatch(
|
||||||
upsreamUrl,
|
upsreamUrl,
|
||||||
prompt,
|
prompt,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
signal
|
||||||
);
|
);
|
||||||
console.log("isrelevantResults in 相关性检查", isRelevantResults);
|
console.log("isrelevantResults in 相关性检查", isRelevantResults);
|
||||||
// 处理每篇文献的相关性结果
|
// 处理每篇文献的相关性结果
|
||||||
|
|
Loading…
Reference in New Issue
Block a user