paper-ai-release-24-07-21/components/chatAI.tsx

234 lines
7.4 KiB
TypeScript
Raw Normal View History

2024-01-18 15:46:18 +08:00
import { Transforms } from "slate";
import { Editor } from "slate";
import { extractText } from "@/utils/others/slateutils";
import {
updateBracketNumbersInDeltaKeepSelection,
convertToSuperscript,
} from "@/utils/others/quillutils";
interface ChatData {
choices: Array<{
delta: {
content?: string;
};
}>;
}
2024-01-21 23:08:25 +08:00
function isValidApiKey(apiKey: string) {
return apiKey && apiKey.trim() !== "";
}
2024-01-18 15:46:18 +08:00
const sendMessageToOpenAI = async (
2024-01-20 13:43:31 +08:00
content: string,
2024-01-18 15:46:18 +08:00
editor: Editor,
2024-01-20 13:43:31 +08:00
selectedModel: "gpt3.5",
2024-01-21 23:08:25 +08:00
apiKey: string,
2024-01-18 23:22:23 +08:00
prompt?: string
2024-01-18 15:46:18 +08:00
) => {
2024-01-21 23:08:25 +08:00
// console.log("apiKey", apiKey);
// console.log("isValidApiKey(apiKey)", isValidApiKey(apiKey).toString());
// console.log(
// " token的值",
// "Bearer " +
// (isValidApiKey(apiKey) ? apiKey : process.env.NEXT_PUBLIC_OPENAI_API_KEY)
// );
2024-01-20 13:43:31 +08:00
//识别应该使用的模型
2024-01-21 23:08:25 +08:00
let model = selectedModel === "gpt3.5" ? "gpt-3.5-turbo" : "gpt-4";
2024-01-18 15:46:18 +08:00
// 设置API请求参数
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
2024-01-21 23:08:25 +08:00
Authorization:
"Bearer " +
(isValidApiKey(apiKey)
? apiKey
: process.env.NEXT_PUBLIC_OPENAI_API_KEY),
2024-01-18 15:46:18 +08:00
},
body: JSON.stringify({
2024-01-20 13:43:31 +08:00
model: model,
2024-01-18 15:46:18 +08:00
stream: true,
messages: [
{
role: "system",
2024-01-21 23:08:25 +08:00
content:
prompt ||
`作为论文写作助手,您的主要任务是根据用户提供的研究主题和上下文,以及相关的研究论文,来撰写和完善学术论文。在撰写过程中,请注意以下要点:
2024-01-18 15:46:18 +08:00
1.使
2024-01-19 15:36:41 +08:00
2.使 [1]**
2024-01-18 15:46:18 +08:00
3.
4.
5.使,
2024-01-19 15:36:41 +08:00
6.
2024-01-18 23:22:23 +08:00
...[1],...[2]`,
2024-01-18 15:46:18 +08:00
},
{
role: "user",
content: content,
},
],
}),
};
console.log("请求的内容\n", content);
// 发送API请求
try {
const response = await fetch(
2024-01-18 23:22:23 +08:00
process.env.NEXT_PUBLIC_AI_URL,
2024-01-18 15:46:18 +08:00
requestOptions
);
const reader = response.body.getReader();
const decoder = new TextDecoder();
await processResult(reader, decoder, editor);
convertToSuperscript(editor);
updateBracketNumbersInDeltaKeepSelection(editor);
} catch (error) {
console.error("Error:", error);
2024-01-21 23:08:25 +08:00
throw error;
2024-01-18 15:46:18 +08:00
}
};
2024-01-21 23:08:25 +08:00
const getTopicFromAI = async (
userMessage: string,
prompt: string,
apiKey: string
) => {
2024-01-18 23:22:23 +08:00
// 设置API请求参数
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
2024-01-21 23:08:25 +08:00
Authorization:
"Bearer " +
(isValidApiKey(apiKey)
? apiKey
: process.env.NEXT_PUBLIC_OPENAI_API_KEY),
2024-01-18 23:22:23 +08:00
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
stream: false,
messages: [
{
role: "system",
content: prompt,
},
{
role: "user",
content: userMessage,
},
],
}),
};
const response = await fetch(process.env.NEXT_PUBLIC_AI_URL, requestOptions);
2024-01-19 15:36:41 +08:00
const data = await response.json();
2024-01-21 23:08:25 +08:00
const topic = data.choices[0].message.content;
return topic; // 获取并返回回复
2024-01-18 23:22:23 +08:00
};
2024-01-20 13:43:31 +08:00
// 给getTopicFromAI函数创建别名
// export const getFromAI = sendMessageToOpenAI;
2024-01-18 15:46:18 +08:00
async function processResult(reader, decoder, editor) {
let chunk = "";
while (true) {
const { done, value } = await reader.read();
if (done) {
console.log("Stream finished");
break;
}
chunk += decoder.decode(value, { stream: true });
// 分割数据块为单独的数据对象
const dataObjects = chunk
.split("\n")
.filter(Boolean)
.map((line) => {
try {
line = line.substring(6); // 移除前面的 "data: "
if (line === "[DONE]") {
console.log("stream finished");
return null;
}
return JSON.parse(line);
} catch (error) {
console.error("Failed to parse line:", line);
console.error("Error:", error);
return null;
}
})
.filter(Boolean);
if (dataObjects.length > 0) {
// 处理每个数据对象
dataObjects.forEach((dataObject) => {
const content = dataObject.choices[0].delta.content;
if (content) {
// 在当前光标位置插入文本
// Transforms.insertText(editor, content); //slate
editor.insertText(editor.getSelection().index, content); //quill
// console.log("成功插入:", content);
}
});
chunk = ""; // 清空chunk以便读取新的数据
}
}
}
2024-01-18 23:22:23 +08:00
export { getTopicFromAI, sendMessageToOpenAI };
2024-01-18 15:46:18 +08:00
// fetch("https://api.openai.com/v1/chat/completions", requestOptions)
// .then((response) => {
// // 获取响应的读取器
// const reader = response.body!.getReader();
// const decoder = new TextDecoder();
// let chunk = "";
// // 处理流式响应
// function processResult(result: any): Promise<void> {
// // if (result.done) return;
// chunk += decoder.decode(result.value, { stream: true });
// // 分割数据块为单独的数据对象
// const dataObjects: ChatData[] = chunk
// .split("\n")
// .filter(Boolean)
// .map((line) => {
// try {
// line = line.substring(6); // 移除前面的 "data: "
// // console.log(line);
// if (line === "[DONE]") {
// console.log("stream finished");
// return null;
// }
// return JSON.parse(line);
// } catch (error) {
// console.error("Failed to parse line:", line);
// console.error("Error:", error);
// return null;
// }
// })
// .filter(Boolean);
// if (dataObjects.length === 0) {
// //如果这里不终止的话,会导致无限循环,程序崩溃
// return Promise.resolve();
// }
// // const dataObjects = JSON.parse(chunk.data);
// // 处理每个数据对象
// dataObjects.forEach((dataObject) => {
// const content = dataObject.choices[0].delta.content;
// if (content) {
// // 在当前光标位置插入文本
// // Transforms.insertText(editor, content); //slate
// editor.insertText(editor.getSelection().index, content); //quill
// // console.log("成功插入:", content);
// }
// });
// chunk = "";
// // 继续读取响应
// return reader.read().then(processResult);
// }