forked from XiaoMo/ChatGPT-Next-Web
Merge branch 'Yidadaa:main' into main
This commit is contained in:
commit
b9895ecadd
14
.babelrc
Normal file
14
.babelrc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"next/babel",
|
||||||
|
{
|
||||||
|
"preset-env": {
|
||||||
|
"targets": {
|
||||||
|
"browsers": ["> 0.25%, not dead"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -14,7 +14,7 @@ One-Click to get well-designed cross-platform ChatGPT web UI.
|
|||||||
[![MacOS][MacOS-image]][download-url]
|
[![MacOS][MacOS-image]][download-url]
|
||||||
[![Linux][Linux-image]][download-url]
|
[![Linux][Linux-image]][download-url]
|
||||||
|
|
||||||
[Web App](https://chatgpt.nextweb.fun/) / [Desktop App](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [Buy Me a Coffee](https://www.buymeacoffee.com/yidadaa)
|
[Web App](https://chatgpt.nextweb.fun/) / [Desktop App](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [Discord](https://discord.gg/YCkeafCafC) / [Buy Me a Coffee](https://www.buymeacoffee.com/yidadaa)
|
||||||
|
|
||||||
[网页版](https://chatgpt.nextweb.fun/) / [客户端](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [反馈](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [QQ 群](https://github.com/Yidadaa/ChatGPT-Next-Web/discussions/1724) / [打赏开发者](https://user-images.githubusercontent.com/16968934/227772541-5bcd52d8-61b7-488c-a203-0330d8006e2b.jpg)
|
[网页版](https://chatgpt.nextweb.fun/) / [客户端](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [反馈](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [QQ 群](https://github.com/Yidadaa/ChatGPT-Next-Web/discussions/1724) / [打赏开发者](https://user-images.githubusercontent.com/16968934/227772541-5bcd52d8-61b7-488c-a203-0330d8006e2b.jpg)
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ import { NextRequest, NextResponse } from "next/server";
|
|||||||
|
|
||||||
export const OPENAI_URL = "api.openai.com";
|
export const OPENAI_URL = "api.openai.com";
|
||||||
const DEFAULT_PROTOCOL = "https";
|
const DEFAULT_PROTOCOL = "https";
|
||||||
const PROTOCOL = process.env.PROTOCOL ?? DEFAULT_PROTOCOL;
|
const PROTOCOL = process.env.PROTOCOL || DEFAULT_PROTOCOL;
|
||||||
const BASE_URL = process.env.BASE_URL ?? OPENAI_URL;
|
const BASE_URL = process.env.BASE_URL || OPENAI_URL;
|
||||||
const DISABLE_GPT4 = !!process.env.DISABLE_GPT4;
|
const DISABLE_GPT4 = !!process.env.DISABLE_GPT4;
|
||||||
|
|
||||||
export async function requestOpenai(req: NextRequest) {
|
export async function requestOpenai(req: NextRequest) {
|
||||||
|
@ -99,7 +99,7 @@ export class ClientApi {
|
|||||||
// 敬告二开开发者们,为了开源大模型的发展,请不要修改上述消息,此消息用于后续数据清洗使用
|
// 敬告二开开发者们,为了开源大模型的发展,请不要修改上述消息,此消息用于后续数据清洗使用
|
||||||
// Please do not modify this message
|
// Please do not modify this message
|
||||||
|
|
||||||
console.log("[Share]", msgs);
|
console.log("[Share]", messages, msgs);
|
||||||
const clientConfig = getClientConfig();
|
const clientConfig = getClientConfig();
|
||||||
const proxyUrl = "/sharegpt";
|
const proxyUrl = "/sharegpt";
|
||||||
const rawUrl = "https://sharegpt.com/api/conversations";
|
const rawUrl = "https://sharegpt.com/api/conversations";
|
||||||
|
@ -101,6 +101,19 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.context-drag {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-drag {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: all ease 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
.context-role {
|
.context-role {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import React, {
|
|||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
Fragment,
|
||||||
} from "react";
|
} from "react";
|
||||||
|
|
||||||
import SendWhiteIcon from "../icons/send-white.svg";
|
import SendWhiteIcon from "../icons/send-white.svg";
|
||||||
@ -975,9 +976,8 @@ export function Chat() {
|
|||||||
const shouldShowClearContextDivider = i === clearContextIndex - 1;
|
const shouldShowClearContextDivider = i === clearContextIndex - 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Fragment key={i}>
|
||||||
<div
|
<div
|
||||||
key={i}
|
|
||||||
className={
|
className={
|
||||||
isUser ? styles["chat-message-user"] : styles["chat-message"]
|
isUser ? styles["chat-message-user"] : styles["chat-message"]
|
||||||
}
|
}
|
||||||
@ -1082,7 +1082,7 @@ export function Chat() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{shouldShowClearContextDivider && <ClearContextDivider />}
|
{shouldShowClearContextDivider && <ClearContextDivider />}
|
||||||
</>
|
</Fragment>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
Modal,
|
Modal,
|
||||||
Select,
|
Select,
|
||||||
showImageModal,
|
showImageModal,
|
||||||
|
showModal,
|
||||||
showToast,
|
showToast,
|
||||||
} from "./ui-lib";
|
} from "./ui-lib";
|
||||||
import { IconButton } from "./button";
|
import { IconButton } from "./button";
|
||||||
@ -244,11 +245,11 @@ export function RenderExport(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const renderMsgs = messages.map((v, i) => {
|
const renderMsgs = messages.map((v, i) => {
|
||||||
const [_, role] = v.id.split(":");
|
const [role, _] = v.id.split(":");
|
||||||
return {
|
return {
|
||||||
id: i.toString(),
|
id: i.toString(),
|
||||||
role: role as any,
|
role: role as any,
|
||||||
content: v.innerHTML,
|
content: role === "user" ? v.textContent ?? "" : v.innerHTML,
|
||||||
date: "",
|
date: "",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -287,7 +288,30 @@ export function PreviewActions(props: {
|
|||||||
.share(msgs)
|
.share(msgs)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!res) return;
|
if (!res) return;
|
||||||
copyToClipboard(res);
|
showModal({
|
||||||
|
title: Locale.Export.Share,
|
||||||
|
children: [
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={res}
|
||||||
|
key="input"
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
maxWidth: "unset",
|
||||||
|
}}
|
||||||
|
readOnly
|
||||||
|
onClick={(e) => e.currentTarget.select()}
|
||||||
|
></input>,
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
<IconButton
|
||||||
|
icon={<CopyIcon />}
|
||||||
|
text={Locale.Chat.Actions.Copy}
|
||||||
|
key="copy"
|
||||||
|
onClick={() => copyToClipboard(res)}
|
||||||
|
/>,
|
||||||
|
],
|
||||||
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.open(res, "_blank");
|
window.open(res, "_blank");
|
||||||
}, 800);
|
}, 800);
|
||||||
|
@ -61,24 +61,36 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
.sidebar-drag {
|
||||||
|
background-color: rgba($color: #000000, $alpha: 0.01);
|
||||||
|
|
||||||
|
svg {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-drag {
|
.sidebar-drag {
|
||||||
$width: 10px;
|
$width: 14px;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: $width;
|
width: $width;
|
||||||
background-color: var(--black);
|
background-color: rgba($color: #000000, $alpha: 0);
|
||||||
cursor: ew-resize;
|
cursor: ew-resize;
|
||||||
opacity: 0;
|
|
||||||
transition: all ease 0.3s;
|
transition: all ease 0.3s;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
&:hover,
|
svg {
|
||||||
&:active {
|
opacity: 0;
|
||||||
opacity: 0.2;
|
margin-left: -2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import CloseIcon from "../icons/close.svg";
|
|||||||
import DeleteIcon from "../icons/delete.svg";
|
import DeleteIcon from "../icons/delete.svg";
|
||||||
import EyeIcon from "../icons/eye.svg";
|
import EyeIcon from "../icons/eye.svg";
|
||||||
import CopyIcon from "../icons/copy.svg";
|
import CopyIcon from "../icons/copy.svg";
|
||||||
|
import DragIcon from "../icons/drag.svg";
|
||||||
|
|
||||||
import { DEFAULT_MASK_AVATAR, Mask, useMaskStore } from "../store/mask";
|
import { DEFAULT_MASK_AVATAR, Mask, useMaskStore } from "../store/mask";
|
||||||
import {
|
import {
|
||||||
@ -42,6 +43,20 @@ import { ModelConfigList } from "./model-config";
|
|||||||
import { FileName, Path } from "../constant";
|
import { FileName, Path } from "../constant";
|
||||||
import { BUILTIN_MASK_STORE } from "../masks";
|
import { BUILTIN_MASK_STORE } from "../masks";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
|
import {
|
||||||
|
DragDropContext,
|
||||||
|
Droppable,
|
||||||
|
Draggable,
|
||||||
|
OnDragEndResponder,
|
||||||
|
} from "@hello-pangea/dnd";
|
||||||
|
|
||||||
|
// drag and drop helper function
|
||||||
|
function reorder<T>(list: T[], startIndex: number, endIndex: number): T[] {
|
||||||
|
const result = [...list];
|
||||||
|
const [removed] = result.splice(startIndex, 1);
|
||||||
|
result.splice(endIndex, 0, removed);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export function MaskAvatar(props: { mask: Mask }) {
|
export function MaskAvatar(props: { mask: Mask }) {
|
||||||
return props.mask.avatar !== DEFAULT_MASK_AVATAR ? (
|
return props.mask.avatar !== DEFAULT_MASK_AVATAR ? (
|
||||||
@ -192,6 +207,7 @@ export function MaskConfig(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ContextPromptItem(props: {
|
function ContextPromptItem(props: {
|
||||||
|
index: number;
|
||||||
prompt: ChatMessage;
|
prompt: ChatMessage;
|
||||||
update: (prompt: ChatMessage) => void;
|
update: (prompt: ChatMessage) => void;
|
||||||
remove: () => void;
|
remove: () => void;
|
||||||
@ -199,53 +215,67 @@ function ContextPromptItem(props: {
|
|||||||
const [focusingInput, setFocusingInput] = useState(false);
|
const [focusingInput, setFocusingInput] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={chatStyle["context-prompt-row"]}>
|
<Draggable draggableId={props.prompt.id || props.index.toString()} index={props.index}>
|
||||||
{!focusingInput && (
|
{(provided) => (
|
||||||
<Select
|
<div
|
||||||
value={props.prompt.role}
|
className={chatStyle["context-prompt-row"]}
|
||||||
className={chatStyle["context-role"]}
|
ref={provided.innerRef}
|
||||||
onChange={(e) =>
|
{...provided.draggableProps}
|
||||||
props.update({
|
{...provided.dragHandleProps}
|
||||||
...props.prompt,
|
|
||||||
role: e.target.value as any,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{ROLES.map((r) => (
|
{!focusingInput && (
|
||||||
<option key={r} value={r}>
|
<>
|
||||||
{r}
|
<div className={chatStyle["context-drag"]}>
|
||||||
</option>
|
<DragIcon />
|
||||||
))}
|
</div>
|
||||||
</Select>
|
<Select
|
||||||
|
value={props.prompt.role}
|
||||||
|
className={chatStyle["context-role"]}
|
||||||
|
onChange={(e) =>
|
||||||
|
props.update({
|
||||||
|
...props.prompt,
|
||||||
|
role: e.target.value as any,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{ROLES.map((r) => (
|
||||||
|
<option key={r} value={r}>
|
||||||
|
{r}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<Input
|
||||||
|
value={props.prompt.content}
|
||||||
|
type="text"
|
||||||
|
className={chatStyle["context-content"]}
|
||||||
|
rows={focusingInput ? 5 : 1}
|
||||||
|
onFocus={() => setFocusingInput(true)}
|
||||||
|
onBlur={() => {
|
||||||
|
setFocusingInput(false);
|
||||||
|
// If the selection is not removed when the user loses focus, some
|
||||||
|
// extensions like "Translate" will always display a floating bar
|
||||||
|
window?.getSelection()?.removeAllRanges();
|
||||||
|
}}
|
||||||
|
onInput={(e) =>
|
||||||
|
props.update({
|
||||||
|
...props.prompt,
|
||||||
|
content: e.currentTarget.value as any,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{!focusingInput && (
|
||||||
|
<IconButton
|
||||||
|
icon={<DeleteIcon />}
|
||||||
|
className={chatStyle["context-delete-button"]}
|
||||||
|
onClick={() => props.remove()}
|
||||||
|
bordered
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
<Input
|
</Draggable>
|
||||||
value={props.prompt.content}
|
|
||||||
type="text"
|
|
||||||
className={chatStyle["context-content"]}
|
|
||||||
rows={focusingInput ? 5 : 1}
|
|
||||||
onFocus={() => setFocusingInput(true)}
|
|
||||||
onBlur={() => {
|
|
||||||
setFocusingInput(false);
|
|
||||||
// If the selection is not removed when the user loses focus, some
|
|
||||||
// extensions like "Translate" will always display a floating bar
|
|
||||||
window?.getSelection()?.removeAllRanges();
|
|
||||||
}}
|
|
||||||
onInput={(e) =>
|
|
||||||
props.update({
|
|
||||||
...props.prompt,
|
|
||||||
content: e.currentTarget.value as any,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{!focusingInput && (
|
|
||||||
<IconButton
|
|
||||||
icon={<DeleteIcon />}
|
|
||||||
className={chatStyle["context-delete-button"]}
|
|
||||||
onClick={() => props.remove()}
|
|
||||||
bordered
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,17 +297,41 @@ export function ContextPrompts(props: {
|
|||||||
props.updateContext((context) => (context[i] = prompt));
|
props.updateContext((context) => (context[i] = prompt));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onDragEnd: OnDragEndResponder = (result) => {
|
||||||
|
if (!result.destination) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newContext = reorder(
|
||||||
|
context,
|
||||||
|
result.source.index,
|
||||||
|
result.destination.index,
|
||||||
|
);
|
||||||
|
props.updateContext((context) => {
|
||||||
|
context.splice(0, context.length, ...newContext);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={chatStyle["context-prompt"]} style={{ marginBottom: 20 }}>
|
<div className={chatStyle["context-prompt"]} style={{ marginBottom: 20 }}>
|
||||||
{context.map((c, i) => (
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
<ContextPromptItem
|
<Droppable droppableId="context-prompt-list">
|
||||||
key={i}
|
{(provided) => (
|
||||||
prompt={c}
|
<div ref={provided.innerRef} {...provided.droppableProps}>
|
||||||
update={(prompt) => updateContextPrompt(i, prompt)}
|
{context.map((c, i) => (
|
||||||
remove={() => removeContextPrompt(i)}
|
<ContextPromptItem
|
||||||
/>
|
index={i}
|
||||||
))}
|
key={c.id}
|
||||||
|
prompt={c}
|
||||||
|
update={(prompt) => updateContextPrompt(i, prompt)}
|
||||||
|
remove={() => removeContextPrompt(i)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{provided.placeholder}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Droppable>
|
||||||
|
</DragDropContext>
|
||||||
|
|
||||||
<div className={chatStyle["context-prompt-row"]}>
|
<div className={chatStyle["context-prompt-row"]}>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
@ -10,6 +10,7 @@ import AddIcon from "../icons/add.svg";
|
|||||||
import CloseIcon from "../icons/close.svg";
|
import CloseIcon from "../icons/close.svg";
|
||||||
import MaskIcon from "../icons/mask.svg";
|
import MaskIcon from "../icons/mask.svg";
|
||||||
import PluginIcon from "../icons/plugin.svg";
|
import PluginIcon from "../icons/plugin.svg";
|
||||||
|
import DragIcon from "../icons/drag.svg";
|
||||||
|
|
||||||
import Locale from "../locales";
|
import Locale from "../locales";
|
||||||
|
|
||||||
@ -198,7 +199,9 @@ export function SideBar(props: { className?: string }) {
|
|||||||
<div
|
<div
|
||||||
className={styles["sidebar-drag"]}
|
className={styles["sidebar-drag"]}
|
||||||
onMouseDown={(e) => onDragMouseDown(e as any)}
|
onMouseDown={(e) => onDragMouseDown(e as any)}
|
||||||
></div>
|
>
|
||||||
|
<DragIcon />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
1
app/icons/drag.svg
Normal file
1
app/icons/drag.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" fill="none"><g opacity="1" transform="translate(0 0) rotate(0)"><mask id="bg-mask-0" fill="white"><use transform="translate(0 0) rotate(0)" xlink:href="#path_0"></use></mask><g mask="url(#bg-mask-0)" ><path id="路径 1" fill-rule="evenodd" style="fill:#333333" opacity="1" d="M6.33663,3.33c0,0.74 -0.6,1.34 -1.34,1.34c-0.73,0 -1.33,-0.6 -1.33,-1.34c0,-0.73 0.6,-1.33 1.33,-1.33c0.74,0 1.34,0.6 1.34,1.33zM4.99663,9.33c-0.73,0 -1.33,-0.59 -1.33,-1.33c0,-0.74 0.6,-1.33 1.33,-1.33c0.74,0 1.34,0.59 1.34,1.33c0,0.74 -0.6,1.33 -1.34,1.33zM4.99663,14c-0.73,0 -1.33,-0.6 -1.33,-1.33c0,-0.74 0.6,-1.34 1.33,-1.34c0.74,0 1.34,0.6 1.34,1.34c0,0.73 -0.6,1.33 -1.34,1.33z"></path><path id="路径 2" fill-rule="evenodd" style="fill:#333333" opacity="1" d="M12.3366,3.33c0,0.74 -0.6,1.34 -1.34,1.34c-0.73,0 -1.32997,-0.6 -1.32997,-1.34c0,-0.73 0.59997,-1.33 1.32997,-1.33c0.74,0 1.34,0.6 1.34,1.33zM10.9966,9.33c-0.73,0 -1.32997,-0.59 -1.32997,-1.33c0,-0.74 0.59997,-1.33 1.32997,-1.33c0.74,0 1.34,0.59 1.34,1.33c0,0.74 -0.6,1.33 -1.34,1.33zM10.9966,14c-0.73,0 -1.32997,-0.6 -1.32997,-1.33c0,-0.74 0.59997,-1.34 1.32997,-1.34c0.74,0 1.34,0.6 1.34,1.34c0,0.73 -0.6,1.33 -1.34,1.33z"></path></g></g><defs><rect id="path_0" x="0" y="0" width="16" height="16" /></defs></svg>
|
After Width: | Height: | Size: 1.4 KiB |
@ -3,8 +3,9 @@ import "./styles/globals.scss";
|
|||||||
import "./styles/markdown.scss";
|
import "./styles/markdown.scss";
|
||||||
import "./styles/highlight.scss";
|
import "./styles/highlight.scss";
|
||||||
import { getClientConfig } from "./config/client";
|
import { getClientConfig } from "./config/client";
|
||||||
|
import { type Metadata } from 'next';
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "ChatGPT Next Web",
|
title: "ChatGPT Next Web",
|
||||||
description: "Your personal ChatGPT Chat Bot.",
|
description: "Your personal ChatGPT Chat Bot.",
|
||||||
viewport: {
|
viewport: {
|
||||||
|
@ -589,7 +589,7 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: StoreKey.Chat,
|
name: StoreKey.Chat,
|
||||||
version: 3,
|
version: 3.1,
|
||||||
migrate(persistedState, version) {
|
migrate(persistedState, version) {
|
||||||
const state = persistedState as any;
|
const state = persistedState as any;
|
||||||
const newState = JSON.parse(JSON.stringify(state)) as ChatStore;
|
const newState = JSON.parse(JSON.stringify(state)) as ChatStore;
|
||||||
@ -617,6 +617,23 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable `enableInjectSystemPrompts` attribute for old sessions.
|
||||||
|
// Resolve issue of old sessions not automatically enabling.
|
||||||
|
if (version < 3.1) {
|
||||||
|
newState.sessions.forEach((s) => {
|
||||||
|
if (
|
||||||
|
// Exclude those already set by user
|
||||||
|
!s.mask.modelConfig.hasOwnProperty("enableInjectSystemPrompts")
|
||||||
|
) {
|
||||||
|
// Because users may have changed this configuration,
|
||||||
|
// the user's current configuration is used instead of the default
|
||||||
|
const config = useAppConfig.getState();
|
||||||
|
s.mask.modelConfig.enableInjectSystemPrompts =
|
||||||
|
config.modelConfig.enableInjectSystemPrompts;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return newState;
|
return newState;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -30,6 +30,9 @@ const nextConfig = {
|
|||||||
images: {
|
images: {
|
||||||
unoptimized: mode === "export",
|
unoptimized: mode === "export",
|
||||||
},
|
},
|
||||||
|
experimental: {
|
||||||
|
forceSwcTransforms: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mode !== "export") {
|
if (mode !== "export") {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "ChatGPT Next Web",
|
"productName": "ChatGPT Next Web",
|
||||||
"version": "2.8.9"
|
"version": "2.9.0"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -5322,14 +5322,14 @@ schema-utils@^3.1.1, schema-utils@^3.2.0:
|
|||||||
ajv-keywords "^3.5.2"
|
ajv-keywords "^3.5.2"
|
||||||
|
|
||||||
semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
|
semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
|
||||||
version "6.3.0"
|
version "6.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
||||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||||
|
|
||||||
semver@^7.3.7:
|
semver@^7.3.7:
|
||||||
version "7.3.8"
|
version "7.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
|
||||||
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
|
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache "^6.0.0"
|
lru-cache "^6.0.0"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user