mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-04 00:56:40 +08:00
Merge branch 'main' of https://github.com/Yidadaa/ChatGPT-Next-Web
This commit is contained in:
commit
6b7b775b28
@ -55,10 +55,6 @@ export function auth(req: NextRequest) {
|
|||||||
req.headers.set("Authorization", `Bearer ${apiKey}`);
|
req.headers.set("Authorization", `Bearer ${apiKey}`);
|
||||||
} else {
|
} else {
|
||||||
console.log("[Auth] admin did not provide an api key");
|
console.log("[Auth] admin did not provide an api key");
|
||||||
return {
|
|
||||||
error: serverConfig.baseUrl?.includes(OPENAI_URL),
|
|
||||||
msg: "admin did not provide an api key",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("[Auth] use user api key");
|
console.log("[Auth] use user api key");
|
||||||
|
@ -30,26 +30,30 @@ export async function requestOpenai(req: NextRequest) {
|
|||||||
controller.abort();
|
controller.abort();
|
||||||
}, 10 * 60 * 1000);
|
}, 10 * 60 * 1000);
|
||||||
|
|
||||||
|
const fetchUrl = `${baseUrl}/${openaiPath}`;
|
||||||
|
const fetchOptions: RequestInit = {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: authValue,
|
||||||
|
...(process.env.OPENAI_ORG_ID && {
|
||||||
|
"OpenAI-Organization": process.env.OPENAI_ORG_ID,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
cache: "no-store",
|
||||||
|
method: req.method,
|
||||||
|
body: req.body,
|
||||||
|
signal: controller.signal,
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await fetch(`${baseUrl}/${openaiPath}`, {
|
const res = await fetch(fetchUrl, fetchOptions);
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
if (res.status === 401) {
|
||||||
Authorization: authValue,
|
// to prevent browser prompt for credentials
|
||||||
...(process.env.OPENAI_ORG_ID && {
|
res.headers.delete("www-authenticate");
|
||||||
"OpenAI-Organization": process.env.OPENAI_ORG_ID,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
cache: "no-store",
|
|
||||||
method: req.method,
|
|
||||||
body: req.body,
|
|
||||||
signal: controller.signal,
|
|
||||||
});
|
|
||||||
} catch (err: unknown) {
|
|
||||||
if (err instanceof Error && err.name === "AbortError") {
|
|
||||||
console.log("Fetch aborted");
|
|
||||||
} else {
|
|
||||||
throw err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
} finally {
|
} finally {
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ export function getHeaders() {
|
|||||||
const accessStore = useAccessStore.getState();
|
const accessStore = useAccessStore.getState();
|
||||||
let headers: Record<string, string> = {
|
let headers: Record<string, string> = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
"x-requested-with": "XMLHttpRequest",
|
||||||
};
|
};
|
||||||
|
|
||||||
const makeBearer = (token: string) => `Bearer ${token.trim()}`;
|
const makeBearer = (token: string) => `Bearer ${token.trim()}`;
|
||||||
|
@ -28,6 +28,7 @@ export const ChatControllerPool = {
|
|||||||
|
|
||||||
remove(sessionIndex: number, messageId: number) {
|
remove(sessionIndex: number, messageId: number) {
|
||||||
const key = this.key(sessionIndex, messageId);
|
const key = this.key(sessionIndex, messageId);
|
||||||
|
this.controllers[key]?.abort();
|
||||||
delete this.controllers[key];
|
delete this.controllers[key];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import Locale from "../../locales";
|
|||||||
import {
|
import {
|
||||||
EventStreamContentType,
|
EventStreamContentType,
|
||||||
fetchEventSource,
|
fetchEventSource,
|
||||||
} from "@microsoft/fetch-event-source";
|
} from "@fortaine/fetch-event-source";
|
||||||
import { prettyObject } from "@/app/utils/format";
|
import { prettyObject } from "@/app/utils/format";
|
||||||
|
|
||||||
export class ChatGPTApi implements LLMApi {
|
export class ChatGPTApi implements LLMApi {
|
||||||
@ -145,6 +145,7 @@ export class ChatGPTApi implements LLMApi {
|
|||||||
},
|
},
|
||||||
onerror(e) {
|
onerror(e) {
|
||||||
options.onError?.(e);
|
options.onError?.(e);
|
||||||
|
throw e;
|
||||||
},
|
},
|
||||||
openWhenHidden: true,
|
openWhenHidden: true,
|
||||||
});
|
});
|
||||||
|
@ -107,3 +107,70 @@
|
|||||||
user-select: text;
|
user-select: text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clear-context {
|
||||||
|
margin: 20px 0 0 0;
|
||||||
|
padding: 4px 0;
|
||||||
|
|
||||||
|
border-top: var(--border-in-light);
|
||||||
|
border-bottom: var(--border-in-light);
|
||||||
|
box-shadow: var(--card-shadow) inset;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
color: var(--black);
|
||||||
|
transition: all ease 0.3s;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
animation: slide-in ease 0.3s;
|
||||||
|
|
||||||
|
$linear: linear-gradient(
|
||||||
|
to right,
|
||||||
|
rgba(0, 0, 0, 0),
|
||||||
|
rgba(0, 0, 0, 1),
|
||||||
|
rgba(0, 0, 0, 0)
|
||||||
|
);
|
||||||
|
mask-image: $linear;
|
||||||
|
|
||||||
|
@mixin show {
|
||||||
|
transform: translateY(0);
|
||||||
|
position: relative;
|
||||||
|
transition: all ease 0.3s;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin hide {
|
||||||
|
transform: translateY(-50%);
|
||||||
|
position: absolute;
|
||||||
|
transition: all ease 0.1s;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tips {
|
||||||
|
@include show;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-revert-btn {
|
||||||
|
color: var(--primary);
|
||||||
|
@include hide;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
border-color: var(--primary);
|
||||||
|
|
||||||
|
.clear-context-tips {
|
||||||
|
@include hide;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-context-revert-btn {
|
||||||
|
@include show;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,6 +14,8 @@ import MaskIcon from "../icons/mask.svg";
|
|||||||
import MaxIcon from "../icons/max.svg";
|
import MaxIcon from "../icons/max.svg";
|
||||||
import MinIcon from "../icons/min.svg";
|
import MinIcon from "../icons/min.svg";
|
||||||
import ResetIcon from "../icons/reload.svg";
|
import ResetIcon from "../icons/reload.svg";
|
||||||
|
import BreakIcon from "../icons/break.svg";
|
||||||
|
import SettingsIcon from "../icons/chat-settings.svg";
|
||||||
|
|
||||||
import LightIcon from "../icons/light.svg";
|
import LightIcon from "../icons/light.svg";
|
||||||
import DarkIcon from "../icons/dark.svg";
|
import DarkIcon from "../icons/dark.svg";
|
||||||
@ -51,13 +53,14 @@ import { IconButton } from "./button";
|
|||||||
import styles from "./home.module.scss";
|
import styles from "./home.module.scss";
|
||||||
import chatStyle from "./chat.module.scss";
|
import chatStyle from "./chat.module.scss";
|
||||||
|
|
||||||
import { ListItem, Modal, showModal } from "./ui-lib";
|
import { ListItem, Modal, showModal, showToast } from "./ui-lib";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant";
|
import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant";
|
||||||
import { Avatar } from "./emoji";
|
import { Avatar } from "./emoji";
|
||||||
import { MaskAvatar, MaskConfig } from "./mask";
|
import { MaskAvatar, MaskConfig } from "./mask";
|
||||||
import { useMaskStore } from "../store/mask";
|
import { useMaskStore } from "../store/mask";
|
||||||
import { useCommand } from "../command";
|
import { useCommand } from "../command";
|
||||||
|
import { prettyObject } from "../utils/format";
|
||||||
|
|
||||||
const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
|
const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
|
||||||
loading: () => <LoadingIcon />,
|
loading: () => <LoadingIcon />,
|
||||||
@ -118,9 +121,13 @@ export function SessionConfigModel(props: { onClose: () => void }) {
|
|||||||
icon={<ResetIcon />}
|
icon={<ResetIcon />}
|
||||||
bordered
|
bordered
|
||||||
text={Locale.Chat.Config.Reset}
|
text={Locale.Chat.Config.Reset}
|
||||||
onClick={() =>
|
onClick={() => {
|
||||||
confirm(Locale.Memory.ResetConfirm) && chatStore.resetSession()
|
if (confirm(Locale.Memory.ResetConfirm)) {
|
||||||
}
|
chatStore.updateCurrentSession(
|
||||||
|
(session) => (session.memoryPrompt = ""),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>,
|
/>,
|
||||||
<IconButton
|
<IconButton
|
||||||
key="copy"
|
key="copy"
|
||||||
@ -288,6 +295,28 @@ export function PromptHints(props: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ClearContextDivider() {
|
||||||
|
const chatStore = useChatStore();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={chatStyle["clear-context"]}
|
||||||
|
onClick={() =>
|
||||||
|
chatStore.updateCurrentSession(
|
||||||
|
(session) => (session.clearContextIndex = -1),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className={chatStyle["clear-context-tips"]}>
|
||||||
|
{Locale.Context.Clear}
|
||||||
|
</div>
|
||||||
|
<div className={chatStyle["clear-context-revert-btn"]}>
|
||||||
|
{Locale.Context.Revert}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function useScrollToBottom() {
|
function useScrollToBottom() {
|
||||||
// for auto-scroll
|
// for auto-scroll
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
@ -320,6 +349,7 @@ export function ChatActions(props: {
|
|||||||
}) {
|
}) {
|
||||||
const config = useAppConfig();
|
const config = useAppConfig();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const chatStore = useChatStore();
|
||||||
|
|
||||||
// switch themes
|
// switch themes
|
||||||
const theme = config.theme;
|
const theme = config.theme;
|
||||||
@ -358,7 +388,7 @@ export function ChatActions(props: {
|
|||||||
className={`${chatStyle["chat-input-action"]} clickable`}
|
className={`${chatStyle["chat-input-action"]} clickable`}
|
||||||
onClick={props.showPromptModal}
|
onClick={props.showPromptModal}
|
||||||
>
|
>
|
||||||
<BrainIcon />
|
<SettingsIcon />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -390,6 +420,22 @@ export function ChatActions(props: {
|
|||||||
>
|
>
|
||||||
<MaskIcon />
|
<MaskIcon />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={`${chatStyle["chat-input-action"]} clickable`}
|
||||||
|
onClick={() => {
|
||||||
|
chatStore.updateCurrentSession((session) => {
|
||||||
|
if (session.clearContextIndex === session.messages.length) {
|
||||||
|
session.clearContextIndex = -1;
|
||||||
|
} else {
|
||||||
|
session.clearContextIndex = session.messages.length;
|
||||||
|
session.memoryPrompt = ""; // will clear memory
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BreakIcon />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -496,13 +542,17 @@ export function Chat() {
|
|||||||
const stopTiming = Date.now() - REQUEST_TIMEOUT_MS;
|
const stopTiming = Date.now() - REQUEST_TIMEOUT_MS;
|
||||||
session.messages.forEach((m) => {
|
session.messages.forEach((m) => {
|
||||||
// check if should stop all stale messages
|
// check if should stop all stale messages
|
||||||
if (new Date(m.date).getTime() < stopTiming) {
|
if (m.isError || new Date(m.date).getTime() < stopTiming) {
|
||||||
if (m.streaming) {
|
if (m.streaming) {
|
||||||
m.streaming = false;
|
m.streaming = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.content.length === 0) {
|
if (m.content.length === 0) {
|
||||||
m.content = "No content in this message.";
|
m.isError = true;
|
||||||
|
m.content = prettyObject({
|
||||||
|
error: true,
|
||||||
|
message: "empty response",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -580,7 +630,9 @@ export function Chat() {
|
|||||||
inputRef.current?.focus();
|
inputRef.current?.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
const context: RenderMessage[] = session.mask.context.slice();
|
const context: RenderMessage[] = session.mask.hideContext
|
||||||
|
? []
|
||||||
|
: session.mask.context.slice();
|
||||||
|
|
||||||
const accessStore = useAccessStore();
|
const accessStore = useAccessStore();
|
||||||
|
|
||||||
@ -595,6 +647,12 @@ export function Chat() {
|
|||||||
context.push(copiedHello);
|
context.push(copiedHello);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clear context index = context length + index in messages
|
||||||
|
const clearContextIndex =
|
||||||
|
(session.clearContextIndex ?? -1) >= 0
|
||||||
|
? session.clearContextIndex! + context.length
|
||||||
|
: -1;
|
||||||
|
|
||||||
// preview messages
|
// preview messages
|
||||||
const messages = context
|
const messages = context
|
||||||
.concat(session.messages as RenderMessage[])
|
.concat(session.messages as RenderMessage[])
|
||||||
@ -729,86 +787,91 @@ export function Chat() {
|
|||||||
!(message.preview || message.content.length === 0);
|
!(message.preview || message.content.length === 0);
|
||||||
const showTyping = message.preview || message.streaming;
|
const showTyping = message.preview || message.streaming;
|
||||||
|
|
||||||
|
const shouldShowClearContextDivider = i === clearContextIndex - 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<>
|
||||||
key={i}
|
<div
|
||||||
className={
|
key={i}
|
||||||
isUser ? styles["chat-message-user"] : styles["chat-message"]
|
className={
|
||||||
}
|
isUser ? styles["chat-message-user"] : styles["chat-message"]
|
||||||
>
|
}
|
||||||
<div className={styles["chat-message-container"]}>
|
>
|
||||||
<div className={styles["chat-message-avatar"]}>
|
<div className={styles["chat-message-container"]}>
|
||||||
{message.role === "user" ? (
|
<div className={styles["chat-message-avatar"]}>
|
||||||
<Avatar avatar={config.avatar} />
|
{message.role === "user" ? (
|
||||||
) : (
|
<Avatar avatar={config.avatar} />
|
||||||
<MaskAvatar mask={session.mask} />
|
) : (
|
||||||
)}
|
<MaskAvatar mask={session.mask} />
|
||||||
</div>
|
)}
|
||||||
{showTyping && (
|
|
||||||
<div className={styles["chat-message-status"]}>
|
|
||||||
{Locale.Chat.Typing}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{showTyping && (
|
||||||
<div className={styles["chat-message-item"]}>
|
<div className={styles["chat-message-status"]}>
|
||||||
{showActions && (
|
{Locale.Chat.Typing}
|
||||||
<div className={styles["chat-message-top-actions"]}>
|
</div>
|
||||||
{message.streaming ? (
|
)}
|
||||||
|
<div className={styles["chat-message-item"]}>
|
||||||
|
{showActions && (
|
||||||
|
<div className={styles["chat-message-top-actions"]}>
|
||||||
|
{message.streaming ? (
|
||||||
|
<div
|
||||||
|
className={styles["chat-message-top-action"]}
|
||||||
|
onClick={() => onUserStop(message.id ?? i)}
|
||||||
|
>
|
||||||
|
{Locale.Chat.Actions.Stop}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className={styles["chat-message-top-action"]}
|
||||||
|
onClick={() => onDelete(message.id ?? i)}
|
||||||
|
>
|
||||||
|
{Locale.Chat.Actions.Delete}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={styles["chat-message-top-action"]}
|
||||||
|
onClick={() => onResend(message.id ?? i)}
|
||||||
|
>
|
||||||
|
{Locale.Chat.Actions.Retry}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={styles["chat-message-top-action"]}
|
className={styles["chat-message-top-action"]}
|
||||||
onClick={() => onUserStop(message.id ?? i)}
|
onClick={() => copyToClipboard(message.content)}
|
||||||
>
|
>
|
||||||
{Locale.Chat.Actions.Stop}
|
{Locale.Chat.Actions.Copy}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
</div>
|
||||||
<>
|
)}
|
||||||
<div
|
<Markdown
|
||||||
className={styles["chat-message-top-action"]}
|
content={message.content}
|
||||||
onClick={() => onDelete(message.id ?? i)}
|
loading={
|
||||||
>
|
(message.preview || message.content.length === 0) &&
|
||||||
{Locale.Chat.Actions.Delete}
|
!isUser
|
||||||
</div>
|
}
|
||||||
<div
|
onContextMenu={(e) => onRightClick(e, message)}
|
||||||
className={styles["chat-message-top-action"]}
|
onDoubleClickCapture={() => {
|
||||||
onClick={() => onResend(message.id ?? i)}
|
if (!isMobileScreen) return;
|
||||||
>
|
setUserInput(message.content);
|
||||||
{Locale.Chat.Actions.Retry}
|
}}
|
||||||
</div>
|
fontSize={fontSize}
|
||||||
</>
|
parentRef={scrollRef}
|
||||||
)}
|
defaultShow={i >= messages.length - 10}
|
||||||
|
/>
|
||||||
<div
|
</div>
|
||||||
className={styles["chat-message-top-action"]}
|
{!isUser && !message.preview && (
|
||||||
onClick={() => copyToClipboard(message.content)}
|
<div className={styles["chat-message-actions"]}>
|
||||||
>
|
<div className={styles["chat-message-action-date"]}>
|
||||||
{Locale.Chat.Actions.Copy}
|
{message.date.toLocaleString()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Markdown
|
|
||||||
content={message.content}
|
|
||||||
loading={
|
|
||||||
(message.preview || message.content.length === 0) &&
|
|
||||||
!isUser
|
|
||||||
}
|
|
||||||
onContextMenu={(e) => onRightClick(e, message)}
|
|
||||||
onDoubleClickCapture={() => {
|
|
||||||
if (!isMobileScreen) return;
|
|
||||||
setUserInput(message.content);
|
|
||||||
}}
|
|
||||||
fontSize={fontSize}
|
|
||||||
parentRef={scrollRef}
|
|
||||||
defaultShow={i >= messages.length - 10}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
{!isUser && !message.preview && (
|
|
||||||
<div className={styles["chat-message-actions"]}>
|
|
||||||
<div className={styles["chat-message-action-date"]}>
|
|
||||||
{message.date.toLocaleString()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{shouldShowClearContextDivider && <ClearContextDivider />}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
@ -104,25 +104,41 @@ export function MaskConfig(props: {
|
|||||||
></input>
|
></input>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem
|
<ListItem
|
||||||
title={Locale.Mask.Config.Sync.Title}
|
title={Locale.Mask.Config.HideContext.Title}
|
||||||
subTitle={Locale.Mask.Config.Sync.SubTitle}
|
subTitle={Locale.Mask.Config.HideContext.SubTitle}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={props.mask.syncGlobalConfig}
|
checked={props.mask.hideContext}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
if (
|
props.updateMask((mask) => {
|
||||||
e.currentTarget.checked &&
|
mask.hideContext = e.currentTarget.checked;
|
||||||
confirm(Locale.Mask.Config.Sync.Confirm)
|
});
|
||||||
) {
|
|
||||||
props.updateMask((mask) => {
|
|
||||||
mask.syncGlobalConfig = e.currentTarget.checked;
|
|
||||||
mask.modelConfig = { ...globalConfig.modelConfig };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
></input>
|
></input>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
{props.shouldSyncFromGlobal ? (
|
||||||
|
<ListItem
|
||||||
|
title={Locale.Mask.Config.Sync.Title}
|
||||||
|
subTitle={Locale.Mask.Config.Sync.SubTitle}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={props.mask.syncGlobalConfig}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (
|
||||||
|
e.currentTarget.checked &&
|
||||||
|
confirm(Locale.Mask.Config.Sync.Confirm)
|
||||||
|
) {
|
||||||
|
props.updateMask((mask) => {
|
||||||
|
mask.syncGlobalConfig = e.currentTarget.checked;
|
||||||
|
mask.modelConfig = { ...globalConfig.modelConfig };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
></input>
|
||||||
|
</ListItem>
|
||||||
|
) : null}
|
||||||
</List>
|
</List>
|
||||||
|
|
||||||
<List>
|
<List>
|
||||||
|
@ -54,13 +54,13 @@
|
|||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
margin-top: 5vh;
|
margin-top: 5vh;
|
||||||
margin-bottom: 5vh;
|
margin-bottom: 2vh;
|
||||||
animation: slide-in ease 0.45s;
|
animation: slide-in ease 0.45s;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
.more {
|
.skip {
|
||||||
font-size: 12px;
|
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,16 +68,26 @@
|
|||||||
.masks {
|
.masks {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
|
|
||||||
|
$linear: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
rgba(0, 0, 0, 0),
|
||||||
|
rgba(0, 0, 0, 1),
|
||||||
|
rgba(0, 0, 0, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
-webkit-mask-image: $linear;
|
||||||
|
mask-image: $linear;
|
||||||
|
|
||||||
animation: slide-in ease 0.5s;
|
animation: slide-in ease 0.5s;
|
||||||
|
|
||||||
.mask-row {
|
.mask-row {
|
||||||
margin-bottom: 10px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
// justify-content: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
@for $i from 1 to 10 {
|
@for $i from 1 to 10 {
|
||||||
&:nth-child(#{$i * 2}) {
|
&:nth-child(#{$i * 2}) {
|
||||||
|
@ -27,32 +27,8 @@ function getIntersectionArea(aRect: DOMRect, bRect: DOMRect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function MaskItem(props: { mask: Mask; onClick?: () => void }) {
|
function MaskItem(props: { mask: Mask; onClick?: () => void }) {
|
||||||
const domRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const changeOpacity = () => {
|
|
||||||
const dom = domRef.current;
|
|
||||||
const parent = document.getElementById(SlotID.AppBody);
|
|
||||||
if (!parent || !dom) return;
|
|
||||||
|
|
||||||
const domRect = dom.getBoundingClientRect();
|
|
||||||
const parentRect = parent.getBoundingClientRect();
|
|
||||||
const intersectionArea = getIntersectionArea(domRect, parentRect);
|
|
||||||
const domArea = domRect.width * domRect.height;
|
|
||||||
const ratio = intersectionArea / domArea;
|
|
||||||
const opacity = ratio > 0.9 ? 1 : 0.4;
|
|
||||||
dom.style.opacity = opacity.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
setTimeout(changeOpacity, 30);
|
|
||||||
|
|
||||||
window.addEventListener("resize", changeOpacity);
|
|
||||||
|
|
||||||
return () => window.removeEventListener("resize", changeOpacity);
|
|
||||||
}, [domRef]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles["mask"]} ref={domRef} onClick={props.onClick}>
|
<div className={styles["mask"]} onClick={props.onClick}>
|
||||||
<MaskAvatar mask={props.mask} />
|
<MaskAvatar mask={props.mask} />
|
||||||
<div className={styles["mask-name"] + " one-line"}>{props.mask.name}</div>
|
<div className={styles["mask-name"] + " one-line"}>{props.mask.name}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -63,32 +39,38 @@ function useMaskGroup(masks: Mask[]) {
|
|||||||
const [groups, setGroups] = useState<Mask[][]>([]);
|
const [groups, setGroups] = useState<Mask[][]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const appBody = document.getElementById(SlotID.AppBody);
|
const computeGroup = () => {
|
||||||
if (!appBody || masks.length === 0) return;
|
const appBody = document.getElementById(SlotID.AppBody);
|
||||||
|
if (!appBody || masks.length === 0) return;
|
||||||
|
|
||||||
const rect = appBody.getBoundingClientRect();
|
const rect = appBody.getBoundingClientRect();
|
||||||
const maxWidth = rect.width;
|
const maxWidth = rect.width;
|
||||||
const maxHeight = rect.height * 0.6;
|
const maxHeight = rect.height * 0.6;
|
||||||
const maskItemWidth = 120;
|
const maskItemWidth = 120;
|
||||||
const maskItemHeight = 50;
|
const maskItemHeight = 50;
|
||||||
|
|
||||||
const randomMask = () => masks[Math.floor(Math.random() * masks.length)];
|
const randomMask = () => masks[Math.floor(Math.random() * masks.length)];
|
||||||
let maskIndex = 0;
|
let maskIndex = 0;
|
||||||
const nextMask = () => masks[maskIndex++ % masks.length];
|
const nextMask = () => masks[maskIndex++ % masks.length];
|
||||||
|
|
||||||
const rows = Math.ceil(maxHeight / maskItemHeight);
|
const rows = Math.ceil(maxHeight / maskItemHeight);
|
||||||
const cols = Math.ceil(maxWidth / maskItemWidth);
|
const cols = Math.ceil(maxWidth / maskItemWidth);
|
||||||
|
|
||||||
const newGroups = new Array(rows)
|
const newGroups = new Array(rows)
|
||||||
.fill(0)
|
.fill(0)
|
||||||
.map((_, _i) =>
|
.map((_, _i) =>
|
||||||
new Array(cols)
|
new Array(cols)
|
||||||
.fill(0)
|
.fill(0)
|
||||||
.map((_, j) => (j < 1 || j > cols - 2 ? randomMask() : nextMask())),
|
.map((_, j) => (j < 1 || j > cols - 2 ? randomMask() : nextMask())),
|
||||||
);
|
);
|
||||||
|
|
||||||
setGroups(newGroups);
|
setGroups(newGroups);
|
||||||
|
};
|
||||||
|
|
||||||
|
computeGroup();
|
||||||
|
|
||||||
|
window.addEventListener("resize", computeGroup);
|
||||||
|
return () => window.removeEventListener("resize", computeGroup);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -105,6 +87,8 @@ export function NewChat() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const config = useAppConfig();
|
const config = useAppConfig();
|
||||||
|
|
||||||
|
const maskRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
|
|
||||||
const startChat = (mask?: Mask) => {
|
const startChat = (mask?: Mask) => {
|
||||||
@ -123,6 +107,13 @@ export function NewChat() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (maskRef.current) {
|
||||||
|
maskRef.current.scrollLeft =
|
||||||
|
(maskRef.current.scrollWidth - maskRef.current.clientWidth) / 2;
|
||||||
|
}
|
||||||
|
}, [groups]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles["new-chat"]}>
|
<div className={styles["new-chat"]}>
|
||||||
<div className={styles["mask-header"]}>
|
<div className={styles["mask-header"]}>
|
||||||
@ -162,24 +153,24 @@ export function NewChat() {
|
|||||||
|
|
||||||
<div className={styles["actions"]}>
|
<div className={styles["actions"]}>
|
||||||
<IconButton
|
<IconButton
|
||||||
text={Locale.NewChat.Skip}
|
|
||||||
onClick={() => startChat()}
|
|
||||||
icon={<LightningIcon />}
|
|
||||||
type="primary"
|
|
||||||
shadow
|
|
||||||
/>
|
|
||||||
|
|
||||||
<IconButton
|
|
||||||
className={styles["more"]}
|
|
||||||
text={Locale.NewChat.More}
|
text={Locale.NewChat.More}
|
||||||
onClick={() => navigate(Path.Masks)}
|
onClick={() => navigate(Path.Masks)}
|
||||||
icon={<EyeIcon />}
|
icon={<EyeIcon />}
|
||||||
bordered
|
bordered
|
||||||
shadow
|
shadow
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
text={Locale.NewChat.Skip}
|
||||||
|
onClick={() => startChat()}
|
||||||
|
icon={<LightningIcon />}
|
||||||
|
type="primary"
|
||||||
|
shadow
|
||||||
|
className={styles["skip"]}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles["masks"]}>
|
<div className={styles["masks"]} ref={maskRef}>
|
||||||
{groups.map((masks, i) => (
|
{groups.map((masks, i) => (
|
||||||
<div key={i} className={styles["mask-row"]}>
|
<div key={i} className={styles["mask-row"]}>
|
||||||
{masks.map((mask, index) => (
|
{masks.map((mask, index) => (
|
||||||
|
1
app/icons/break.svg
Normal file
1
app/icons/break.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)"><g opacity="1" transform="translate(1.0001220703125 2) rotate(0)"><path id="路径 1" style="fill:#333333; opacity:1;" d="M13.275,-0.27515c0.261,0.26101 0.3915,0.57606 0.3915,0.94515v10.66c0,0.36907 -0.1305,0.68413 -0.3915,0.9452c-0.261,0.261 -0.57603,0.3915 -0.9451,0.3915h-10.66002c-0.36909,0 -0.68415,-0.1305 -0.94516,-0.3915c-0.26101,-0.26107 -0.39151,-0.57613 -0.39151,-0.9452v-10.66c0,-0.3691 0.1305,-0.68415 0.39151,-0.94515c0.26101,-0.26101 0.57606,-0.39151 0.94516,-0.39151h10.66002c0.36907,0 0.6841,0.1305 0.9451,0.39151zM1.66655,11.33c0,0.0022 0.00111,0.0033 0.00333,0.0033h10.66002c0.0022,0 0.0033,-0.0011 0.0033,-0.0033v-10.66c0,-0.00222 -0.0011,-0.00333 -0.0033,-0.00333l-10.66002,0c-0.00222,0 -0.00333,0.00111 -0.00333,0.00333z"></path><path id="路径 2" style="fill:#333333; opacity:1;" d="M9.76327,7.50715c-0.02999,0.02563 -0.06201,0.04842 -0.09604,0.06837c-0.03403,0.01995 -0.06956,0.03674 -0.10658,0.05039c-0.03702,0.01364 -0.07495,0.02391 -0.11379,0.03082c-0.03885,0.00691 -0.07799,0.01035 -0.11744,0.0103c-0.03945,-0.00004 -0.07859,-0.00356 -0.11742,-0.01055c-0.03883,-0.00699 -0.07674,-0.01734 -0.11373,-0.03106c-0.03699,-0.01372 -0.07248,-0.03059 -0.10647,-0.05061c-0.03399,-0.02002 -0.06596,-0.04288 -0.0959,-0.06858l-1.89578,-1.62728l-1.89578,1.62728c-0.02993,0.0257 -0.0619,0.04856 -0.09589,0.06858c-0.03399,0.02002 -0.06949,0.03689 -0.10648,0.05061c-0.03699,0.01372 -0.07489,0.02407 -0.11372,0.03106c-0.03883,0.00699 -0.07797,0.01051 -0.11742,0.01055c-0.03945,0.00005 -0.0786,-0.00339 -0.11744,-0.0103c-0.03885,-0.00691 -0.07678,-0.01718 -0.11379,-0.03082c-0.03702,-0.01365 -0.07255,-0.03044 -0.10658,-0.05039c-0.03404,-0.01995 -0.06605,-0.04274 -0.09604,-0.06837l-1.90593,-1.629l-1.89671,1.62808c-0.06708,0.05758 -0.14263,0.10013 -0.22664,0.12766c-0.08401,0.02753 -0.17009,0.03793 -0.25824,0.03121c-0.08815,-0.00671 -0.17166,-0.03004 -0.25053,-0.06998c-0.07887,-0.03994 -0.14709,-0.09345 -0.20467,-0.16054c-0.02851,-0.03321 -0.05351,-0.06889 -0.07499,-0.10703c-0.02148,-0.03814 -0.03904,-0.07801 -0.05267,-0.11961c-0.01363,-0.04159 -0.02307,-0.08412 -0.02832,-0.12758c-0.00525,-0.04346 -0.00622,-0.08701 -0.00289,-0.13066c0.00333,-0.04365 0.01088,-0.08655 0.02266,-0.12871c0.01178,-0.04216 0.02755,-0.08277 0.04733,-0.12182c0.01978,-0.03905 0.04317,-0.07579 0.07019,-0.11024c0.02701,-0.03444 0.05713,-0.06592 0.09035,-0.09443l2.32999,-2c0.02994,-0.02569 0.06191,-0.04855 0.0959,-0.06857c0.03399,-0.02003 0.06948,-0.0369 0.10647,-0.05062c0.03699,-0.01372 0.0749,-0.02407 0.11373,-0.03106c0.03883,-0.00699 0.07797,-0.01051 0.11742,-0.01055c0.03945,-0.00004 0.0786,0.00339 0.11744,0.0103c0.03884,0.00691 0.07677,0.01718 0.11379,0.03082c0.03702,0.01365 0.07255,0.03044 0.10658,0.05039c0.03404,0.01995 0.06605,0.04274 0.09604,0.06837l1.90592,1.629l1.89671,-1.62808c0.02998,-0.02573 0.062,-0.04862 0.09605,-0.06866c0.03405,-0.02005 0.0696,-0.03693 0.10665,-0.05065c0.03705,-0.01372 0.07503,-0.02407 0.11392,-0.03104c0.03889,-0.00697 0.07809,-0.01045 0.1176,-0.01045c0.03951,0 0.07872,0.00348 0.11761,0.01045c0.03889,0.00697 0.07686,0.01732 0.11391,0.03104c0.03705,0.01372 0.0726,0.0306 0.10665,0.05065c0.03405,0.02004 0.06607,0.04293 0.09605,0.06866l1.89671,1.62808l1.90595,-1.629c0.03,-0.02563 0.062,-0.04842 0.096,-0.06837c0.03407,-0.01995 0.0696,-0.03674 0.1066,-0.05038c0.037,-0.01365 0.07493,-0.02392 0.1138,-0.03083c0.03887,-0.00691 0.078,-0.01034 0.1174,-0.0103c0.03947,0.00004 0.0786,0.00356 0.1174,0.01055c0.03887,0.00699 0.0768,0.01734 0.1138,0.03106c0.037,0.01372 0.07247,0.03059 0.1064,0.05062c0.034,0.02002 0.06597,0.04288 0.0959,0.06857l2.33,2c0.06713,0.05758 0.12067,0.12581 0.1606,0.20468c0.03993,0.07887 0.06327,0.16237 0.07,0.25052c0.00667,0.08815 -0.00377,0.17424 -0.0313,0.25825c-0.02747,0.08401 -0.07,0.15955 -0.1276,0.22663c-0.02853,0.03322 -0.06,0.06334 -0.0944,0.09035c-0.03447,0.02701 -0.07123,0.05041 -0.1103,0.07019c-0.03907,0.01977 -0.07967,0.03555 -0.1218,0.04733c-0.04213,0.01177 -0.08503,0.01932 -0.1287,0.02265c-0.04367,0.00333 -0.08723,0.00236 -0.1307,-0.00289c-0.04347,-0.00525 -0.086,-0.01469 -0.1276,-0.02832c-0.0416,-0.01363 -0.08147,-0.03118 -0.1196,-0.05267c-0.03813,-0.02148 -0.0738,-0.04648 -0.107,-0.07499l-1.8967,-1.62808z"></path></g><g opacity="1" transform="translate(0 0) rotate(0)"><mask id="bg-mask-0" fill="white"><use xlink:href="#path_0"></use></mask><g mask="url(#bg-mask-0)" ></g></g></g><defs><rect id="path_0" x="0" y="0" width="16" height="16" /></defs></svg>
|
After Width: | Height: | Size: 4.5 KiB |
1
app/icons/chat-settings.svg
Normal file
1
app/icons/chat-settings.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 9.0 KiB |
@ -31,8 +31,8 @@ const cn = {
|
|||||||
},
|
},
|
||||||
Send: "发送",
|
Send: "发送",
|
||||||
Config: {
|
Config: {
|
||||||
Reset: "重置默认",
|
Reset: "清除记忆",
|
||||||
SaveAs: "另存为面具",
|
SaveAs: "存为面具",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Export: {
|
Export: {
|
||||||
@ -47,8 +47,8 @@ const cn = {
|
|||||||
EmptyContent: "对话内容过短,无需总结",
|
EmptyContent: "对话内容过短,无需总结",
|
||||||
Send: "自动压缩聊天记录并作为上下文发送",
|
Send: "自动压缩聊天记录并作为上下文发送",
|
||||||
Copy: "复制摘要",
|
Copy: "复制摘要",
|
||||||
Reset: "重置对话",
|
Reset: "[unused]",
|
||||||
ResetConfirm: "重置后将清空当前对话记录以及历史摘要,确认重置?",
|
ResetConfirm: "确认清空历史摘要?",
|
||||||
},
|
},
|
||||||
Home: {
|
Home: {
|
||||||
NewChat: "新的聊天",
|
NewChat: "新的聊天",
|
||||||
@ -160,12 +160,11 @@ const cn = {
|
|||||||
BotHello: "有什么可以帮你的吗",
|
BotHello: "有什么可以帮你的吗",
|
||||||
Error: "出错了,稍后重试吧",
|
Error: "出错了,稍后重试吧",
|
||||||
Prompt: {
|
Prompt: {
|
||||||
History: (content: string) =>
|
History: (content: string) => "这是历史聊天总结作为前情提要:" + content,
|
||||||
"这是 ai 和用户的历史聊天总结作为前情提要:" + content,
|
|
||||||
Topic:
|
Topic:
|
||||||
"使用四到五个字直接返回这句话的简要主题,不要解释、不要标点、不要语气词、不要多余文本,如果没有主题,请直接返回“闲聊”",
|
"使用四到五个字直接返回这句话的简要主题,不要解释、不要标点、不要语气词、不要多余文本,如果没有主题,请直接返回“闲聊”",
|
||||||
Summarize:
|
Summarize:
|
||||||
"简要总结一下你和用户的对话,用作后续的上下文提示 prompt,控制在 200 字以内",
|
"简要总结一下对话内容,用作后续的上下文提示 prompt,控制在 200 字以内",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Copy: {
|
Copy: {
|
||||||
@ -173,9 +172,11 @@ const cn = {
|
|||||||
Failed: "复制失败,请赋予剪切板权限",
|
Failed: "复制失败,请赋予剪切板权限",
|
||||||
},
|
},
|
||||||
Context: {
|
Context: {
|
||||||
Toast: (x: any) => `已设置 ${x} 条前置上下文`,
|
Toast: (x: any) => `包含 ${x} 条预设提示词`,
|
||||||
Edit: "当前对话设置",
|
Edit: "当前对话设置",
|
||||||
Add: "新增预设对话",
|
Add: "新增预设对话",
|
||||||
|
Clear: "上下文已清除",
|
||||||
|
Revert: "恢复上下文",
|
||||||
},
|
},
|
||||||
Plugin: {
|
Plugin: {
|
||||||
Name: "插件",
|
Name: "插件",
|
||||||
@ -210,6 +211,10 @@ const cn = {
|
|||||||
SubTitle: "当前对话是否使用全局模型设置",
|
SubTitle: "当前对话是否使用全局模型设置",
|
||||||
Confirm: "当前对话的自定义设置将会被自动覆盖,确认启用全局设置?",
|
Confirm: "当前对话的自定义设置将会被自动覆盖,确认启用全局设置?",
|
||||||
},
|
},
|
||||||
|
HideContext: {
|
||||||
|
Title: "隐藏预设对话",
|
||||||
|
SubTitle: "隐藏后预设对话不会出现在聊天界面",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NewChat: {
|
NewChat: {
|
||||||
|
@ -163,12 +163,11 @@ const en: RequiredLocaleType = {
|
|||||||
Error: "Something went wrong, please try again later.",
|
Error: "Something went wrong, please try again later.",
|
||||||
Prompt: {
|
Prompt: {
|
||||||
History: (content: string) =>
|
History: (content: string) =>
|
||||||
"This is a summary of the chat history between the AI and the user as a recap: " +
|
"This is a summary of the chat history as a recap: " + content,
|
||||||
content,
|
|
||||||
Topic:
|
Topic:
|
||||||
"Please generate a four to five word title summarizing our conversation without any lead-in, punctuation, quotation marks, periods, symbols, or additional text. Remove enclosing quotation marks.",
|
"Please generate a four to five word title summarizing our conversation without any lead-in, punctuation, quotation marks, periods, symbols, or additional text. Remove enclosing quotation marks.",
|
||||||
Summarize:
|
Summarize:
|
||||||
"Summarize our discussion briefly in 200 words or less to use as a prompt for future context.",
|
"Summarize the discussion briefly in 200 words or less to use as a prompt for future context.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Copy: {
|
Copy: {
|
||||||
@ -179,6 +178,8 @@ const en: RequiredLocaleType = {
|
|||||||
Toast: (x: any) => `With ${x} contextual prompts`,
|
Toast: (x: any) => `With ${x} contextual prompts`,
|
||||||
Edit: "Contextual and Memory Prompts",
|
Edit: "Contextual and Memory Prompts",
|
||||||
Add: "Add a Prompt",
|
Add: "Add a Prompt",
|
||||||
|
Clear: "Context Cleared",
|
||||||
|
Revert: "Revert",
|
||||||
},
|
},
|
||||||
Plugin: {
|
Plugin: {
|
||||||
Name: "Plugin",
|
Name: "Plugin",
|
||||||
@ -213,15 +214,19 @@ const en: RequiredLocaleType = {
|
|||||||
SubTitle: "Use global config in this chat",
|
SubTitle: "Use global config in this chat",
|
||||||
Confirm: "Confirm to override custom config with global config?",
|
Confirm: "Confirm to override custom config with global config?",
|
||||||
},
|
},
|
||||||
|
HideContext: {
|
||||||
|
Title: "Hide Context Prompts",
|
||||||
|
SubTitle: "Do not show in-context prompts in chat",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NewChat: {
|
NewChat: {
|
||||||
Return: "Return",
|
Return: "Return",
|
||||||
Skip: "Skip",
|
Skip: "Just Start",
|
||||||
Title: "Pick a Mask",
|
Title: "Pick a Mask",
|
||||||
SubTitle: "Chat with the Soul behind the Mask",
|
SubTitle: "Chat with the Soul behind the Mask",
|
||||||
More: "Find More",
|
More: "Find More",
|
||||||
NotShow: "Not Show Again",
|
NotShow: "Never Show Again",
|
||||||
ConfirmNoShow: "Confirm to disable?You can enable it in settings later.",
|
ConfirmNoShow: "Confirm to disable?You can enable it in settings later.",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import { trimTopic } from "../utils";
|
|||||||
|
|
||||||
import Locale from "../locales";
|
import Locale from "../locales";
|
||||||
import { showToast } from "../components/ui-lib";
|
import { showToast } from "../components/ui-lib";
|
||||||
import { ModelType, useAppConfig } from "./config";
|
import { ModelType } from "./config";
|
||||||
import { createEmptyMask, Mask } from "./mask";
|
import { createEmptyMask, Mask } from "./mask";
|
||||||
import { StoreKey } from "../constant";
|
import { StoreKey } from "../constant";
|
||||||
import { api, RequestMessage } from "../client/api";
|
import { api, RequestMessage } from "../client/api";
|
||||||
@ -45,6 +45,7 @@ export interface ChatSession {
|
|||||||
stat: ChatStat;
|
stat: ChatStat;
|
||||||
lastUpdate: number;
|
lastUpdate: number;
|
||||||
lastSummarizeIndex: number;
|
lastSummarizeIndex: number;
|
||||||
|
clearContextIndex?: number;
|
||||||
|
|
||||||
mask: Mask;
|
mask: Mask;
|
||||||
}
|
}
|
||||||
@ -277,13 +278,17 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
config: { ...modelConfig, stream: true },
|
config: { ...modelConfig, stream: true },
|
||||||
onUpdate(message) {
|
onUpdate(message) {
|
||||||
botMessage.streaming = true;
|
botMessage.streaming = true;
|
||||||
botMessage.content = message;
|
if (message) {
|
||||||
|
botMessage.content = message;
|
||||||
|
}
|
||||||
set(() => ({}));
|
set(() => ({}));
|
||||||
},
|
},
|
||||||
onFinish(message) {
|
onFinish(message) {
|
||||||
botMessage.streaming = false;
|
botMessage.streaming = false;
|
||||||
botMessage.content = message;
|
if (message) {
|
||||||
get().onNewMessage(botMessage);
|
botMessage.content = message;
|
||||||
|
get().onNewMessage(botMessage);
|
||||||
|
}
|
||||||
ChatControllerPool.remove(
|
ChatControllerPool.remove(
|
||||||
sessionIndex,
|
sessionIndex,
|
||||||
botMessage.id ?? messageIndex,
|
botMessage.id ?? messageIndex,
|
||||||
@ -292,12 +297,12 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
const isAborted = error.message.includes("aborted");
|
const isAborted = error.message.includes("aborted");
|
||||||
if (
|
botMessage.content =
|
||||||
botMessage.content !== Locale.Error.Unauthorized &&
|
"\n\n" +
|
||||||
!isAborted
|
prettyObject({
|
||||||
) {
|
error: true,
|
||||||
botMessage.content += "\n\n" + prettyObject(error);
|
message: error.message,
|
||||||
}
|
});
|
||||||
botMessage.streaming = false;
|
botMessage.streaming = false;
|
||||||
userMessage.isError = !isAborted;
|
userMessage.isError = !isAborted;
|
||||||
botMessage.isError = !isAborted;
|
botMessage.isError = !isAborted;
|
||||||
@ -308,7 +313,7 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
botMessage.id ?? messageIndex,
|
botMessage.id ?? messageIndex,
|
||||||
);
|
);
|
||||||
|
|
||||||
console.error("[Chat] error ", error);
|
console.error("[Chat] failed ", error);
|
||||||
},
|
},
|
||||||
onController(controller) {
|
onController(controller) {
|
||||||
// collect controller for stop/retry
|
// collect controller for stop/retry
|
||||||
@ -337,7 +342,12 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
getMessagesWithMemory() {
|
getMessagesWithMemory() {
|
||||||
const session = get().currentSession();
|
const session = get().currentSession();
|
||||||
const modelConfig = session.mask.modelConfig;
|
const modelConfig = session.mask.modelConfig;
|
||||||
const messages = session.messages.filter((msg) => !msg.isError);
|
|
||||||
|
// wont send cleared context messages
|
||||||
|
const clearedContextMessages = session.messages.slice(
|
||||||
|
(session.clearContextIndex ?? -1) + 1,
|
||||||
|
);
|
||||||
|
const messages = clearedContextMessages.filter((msg) => !msg.isError);
|
||||||
const n = messages.length;
|
const n = messages.length;
|
||||||
|
|
||||||
const context = session.mask.context.slice();
|
const context = session.mask.context.slice();
|
||||||
@ -358,17 +368,17 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
n - modelConfig.historyMessageCount,
|
n - modelConfig.historyMessageCount,
|
||||||
);
|
);
|
||||||
const longTermMemoryMessageIndex = session.lastSummarizeIndex;
|
const longTermMemoryMessageIndex = session.lastSummarizeIndex;
|
||||||
const oldestIndex = Math.max(
|
const mostRecentIndex = Math.max(
|
||||||
shortTermMemoryMessageIndex,
|
shortTermMemoryMessageIndex,
|
||||||
longTermMemoryMessageIndex,
|
longTermMemoryMessageIndex,
|
||||||
);
|
);
|
||||||
const threshold = modelConfig.compressMessageLengthThreshold;
|
const threshold = modelConfig.compressMessageLengthThreshold * 2;
|
||||||
|
|
||||||
// get recent messages as many as possible
|
// get recent messages as many as possible
|
||||||
const reversedRecentMessages = [];
|
const reversedRecentMessages = [];
|
||||||
for (
|
for (
|
||||||
let i = n - 1, count = 0;
|
let i = n - 1, count = 0;
|
||||||
i >= oldestIndex && count < threshold;
|
i >= mostRecentIndex && count < threshold;
|
||||||
i -= 1
|
i -= 1
|
||||||
) {
|
) {
|
||||||
const msg = messages[i];
|
const msg = messages[i];
|
||||||
@ -406,15 +416,15 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
const session = get().currentSession();
|
const session = get().currentSession();
|
||||||
|
|
||||||
// remove error messages if any
|
// remove error messages if any
|
||||||
const cleanMessages = session.messages.filter((msg) => !msg.isError);
|
const messages = session.messages;
|
||||||
|
|
||||||
// should summarize topic after chating more than 50 words
|
// should summarize topic after chating more than 50 words
|
||||||
const SUMMARIZE_MIN_LEN = 50;
|
const SUMMARIZE_MIN_LEN = 50;
|
||||||
if (
|
if (
|
||||||
session.topic === DEFAULT_TOPIC &&
|
session.topic === DEFAULT_TOPIC &&
|
||||||
countMessages(cleanMessages) >= SUMMARIZE_MIN_LEN
|
countMessages(messages) >= SUMMARIZE_MIN_LEN
|
||||||
) {
|
) {
|
||||||
const topicMessages = cleanMessages.concat(
|
const topicMessages = messages.concat(
|
||||||
createMessage({
|
createMessage({
|
||||||
role: "user",
|
role: "user",
|
||||||
content: Locale.Store.Prompt.Topic,
|
content: Locale.Store.Prompt.Topic,
|
||||||
@ -436,9 +446,13 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const modelConfig = session.mask.modelConfig;
|
const modelConfig = session.mask.modelConfig;
|
||||||
let toBeSummarizedMsgs = cleanMessages.slice(
|
const summarizeIndex = Math.max(
|
||||||
session.lastSummarizeIndex,
|
session.lastSummarizeIndex,
|
||||||
|
session.clearContextIndex ?? 0,
|
||||||
);
|
);
|
||||||
|
let toBeSummarizedMsgs = messages
|
||||||
|
.filter((msg) => !msg.isError)
|
||||||
|
.slice(summarizeIndex);
|
||||||
|
|
||||||
const historyMsgLength = countMessages(toBeSummarizedMsgs);
|
const historyMsgLength = countMessages(toBeSummarizedMsgs);
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ export const ALL_MODELS = [
|
|||||||
available: ENABLE_GPT4,
|
available: ENABLE_GPT4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ext-davinci-002-render-sha-mobile",
|
name: "text-davinci-002-render-sha-mobile",
|
||||||
available: true,
|
available: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -106,13 +106,13 @@ export const ALL_MODELS = [
|
|||||||
},
|
},
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type ModelType = typeof ALL_MODELS[number]["name"];
|
export type ModelType = (typeof ALL_MODELS)[number]["name"];
|
||||||
|
|
||||||
export function limitNumber(
|
export function limitNumber(
|
||||||
x: number,
|
x: number,
|
||||||
min: number,
|
min: number,
|
||||||
max: number,
|
max: number,
|
||||||
defaultValue: number
|
defaultValue: number,
|
||||||
) {
|
) {
|
||||||
if (typeof x !== "number" || isNaN(x)) {
|
if (typeof x !== "number" || isNaN(x)) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
@ -171,6 +171,6 @@ export const useAppConfig = create<ChatConfigStore>()(
|
|||||||
|
|
||||||
return state;
|
return state;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
@ -10,6 +10,7 @@ export type Mask = {
|
|||||||
id: number;
|
id: number;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
hideContext?: boolean;
|
||||||
context: ChatMessage[];
|
context: ChatMessage[];
|
||||||
syncGlobalConfig?: boolean;
|
syncGlobalConfig?: boolean;
|
||||||
modelConfig: ModelConfig;
|
modelConfig: ModelConfig;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
export function prettyObject(msg: any) {
|
export function prettyObject(msg: any) {
|
||||||
const prettyMsg = [
|
if (typeof msg !== "string") {
|
||||||
"```json\n",
|
msg = JSON.stringify(msg, null, " ");
|
||||||
JSON.stringify(msg, null, " "),
|
}
|
||||||
"\n```",
|
const prettyMsg = ["```json", msg, "```"].join("\n");
|
||||||
].join("");
|
|
||||||
return prettyMsg;
|
return prettyMsg;
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,13 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hello-pangea/dnd": "^16.2.0",
|
"@hello-pangea/dnd": "^16.2.0",
|
||||||
"@microsoft/fetch-event-source": "^2.0.1",
|
"@fortaine/fetch-event-source": "^3.0.6",
|
||||||
"@svgr/webpack": "^6.5.1",
|
"@svgr/webpack": "^6.5.1",
|
||||||
"@vercel/analytics": "^0.1.11",
|
"@vercel/analytics": "^0.1.11",
|
||||||
"emoji-picker-react": "^4.4.7",
|
"emoji-picker-react": "^4.4.7",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"mermaid": "^10.1.0",
|
"mermaid": "^10.1.0",
|
||||||
"next": "^13.4.2",
|
"next": "^13.4.3",
|
||||||
"node-fetch": "^3.3.1",
|
"node-fetch": "^3.3.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
118
yarn.lock
118
yarn.lock
@ -1032,6 +1032,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.37.0.tgz#cf1b5fa24217fe007f6487a26d765274925efa7d"
|
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.37.0.tgz#cf1b5fa24217fe007f6487a26d765274925efa7d"
|
||||||
integrity sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==
|
integrity sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==
|
||||||
|
|
||||||
|
"@fortaine/fetch-event-source@^3.0.6":
|
||||||
|
version "3.0.6"
|
||||||
|
resolved "https://registry.npmmirror.com/@fortaine/fetch-event-source/-/fetch-event-source-3.0.6.tgz#b8552a2ca2c5202f5699b93a92be0188d422b06e"
|
||||||
|
integrity sha512-621GAuLMvKtyZQ3IA6nlDWhV1V/7PGOTNIGLUifxt0KzM+dZIweJ6F3XvQF3QnqeNfS1N7WQ0Kil1Di/lhChEw==
|
||||||
|
|
||||||
"@hello-pangea/dnd@^16.2.0":
|
"@hello-pangea/dnd@^16.2.0":
|
||||||
version "16.2.0"
|
version "16.2.0"
|
||||||
resolved "https://registry.npmmirror.com/@hello-pangea/dnd/-/dnd-16.2.0.tgz#58cbadeb56f8c7a381da696bb7aa3bfbb87876ec"
|
resolved "https://registry.npmmirror.com/@hello-pangea/dnd/-/dnd-16.2.0.tgz#58cbadeb56f8c7a381da696bb7aa3bfbb87876ec"
|
||||||
@ -1111,15 +1116,10 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" ">=16.0.0"
|
"@types/react" ">=16.0.0"
|
||||||
|
|
||||||
"@microsoft/fetch-event-source@^2.0.1":
|
"@next/env@13.4.3":
|
||||||
version "2.0.1"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz#9ceecc94b49fbaa15666e38ae8587f64acce007d"
|
resolved "https://registry.npmmirror.com/@next/env/-/env-13.4.3.tgz#cb00bdd43a0619a79a52c9336df8a0aa84f8f4bf"
|
||||||
integrity sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==
|
integrity sha512-pa1ErjyFensznttAk3EIv77vFbfSYT6cLzVRK5jx4uiRuCQo+m2wCFAREaHKIy63dlgvOyMlzh6R8Inu8H3KrQ==
|
||||||
|
|
||||||
"@next/env@13.4.2":
|
|
||||||
version "13.4.2"
|
|
||||||
resolved "https://registry.npmmirror.com/@next/env/-/env-13.4.2.tgz#cf3ebfd523a33d8404c1216e02ac8d856a73170e"
|
|
||||||
integrity sha512-Wqvo7lDeS0KGwtwg9TT9wKQ8raelmUxt+TQKWvG/xKfcmDXNOtCuaszcfCF8JzlBG1q0VhpI6CKaRMbVPMDWgw==
|
|
||||||
|
|
||||||
"@next/eslint-plugin-next@13.2.3":
|
"@next/eslint-plugin-next@13.2.3":
|
||||||
version "13.2.3"
|
version "13.2.3"
|
||||||
@ -1128,50 +1128,50 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
glob "7.1.7"
|
glob "7.1.7"
|
||||||
|
|
||||||
"@next/swc-darwin-arm64@13.4.2":
|
"@next/swc-darwin-arm64@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.2.tgz#d0b497df972bd02eee3bc823d6a76c2cc8b733ef"
|
resolved "https://registry.npmmirror.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.3.tgz#2d6c99dd5afbcce37e4ba0f64196317a1259034d"
|
||||||
integrity sha512-6BBlqGu3ewgJflv9iLCwO1v1hqlecaIH2AotpKfVUEzUxuuDNJQZ2a4KLb4MBl8T9/vca1YuWhSqtbF6ZuUJJw==
|
integrity sha512-yx18udH/ZmR4Bw4M6lIIPE3JxsAZwo04iaucEfA2GMt1unXr2iodHUX/LAKNyi6xoLP2ghi0E+Xi1f4Qb8f1LQ==
|
||||||
|
|
||||||
"@next/swc-darwin-x64@13.4.2":
|
"@next/swc-darwin-x64@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.2.tgz#09a800bed8dfe4beec4cbf14092f9c22db24470b"
|
resolved "https://registry.npmmirror.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.3.tgz#162b15fb8a54d9f64e69c898ebeb55b7dac9bddd"
|
||||||
integrity sha512-iZuYr7ZvGLPjPmfhhMl0ISm+z8EiyLBC1bLyFwGBxkWmPXqdJ60mzuTaDSr5WezDwv0fz32HB7JHmRC6JVHSZg==
|
integrity sha512-Mi8xJWh2IOjryAM1mx18vwmal9eokJ2njY4nDh04scy37F0LEGJ/diL6JL6kTXi0UfUCGbMsOItf7vpReNiD2A==
|
||||||
|
|
||||||
"@next/swc-linux-arm64-gnu@13.4.2":
|
"@next/swc-linux-arm64-gnu@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.2.tgz#b7ade28834564120b0b25ffa0b79d75982d290bc"
|
resolved "https://registry.npmmirror.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.3.tgz#aee57422f11183d6a2e4a2e8aa23b9285873e18f"
|
||||||
integrity sha512-2xVabFtIge6BJTcJrW8YuUnYTuQjh4jEuRuS2mscyNVOj6zUZkom3CQg+egKOoS+zh2rrro66ffSKIS+ztFJTg==
|
integrity sha512-aBvtry4bxJ1xwKZ/LVPeBGBwWVwxa4bTnNkRRw6YffJnn/f4Tv4EGDPaVeYHZGQVA56wsGbtA6nZMuWs/EIk4Q==
|
||||||
|
|
||||||
"@next/swc-linux-arm64-musl@13.4.2":
|
"@next/swc-linux-arm64-musl@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.2.tgz#f5420548234d35251630ddaa2e9a7dc32337a887"
|
resolved "https://registry.npmmirror.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.3.tgz#c10b6aaaa47b341c6c9ea15f8b0ddb37e255d035"
|
||||||
integrity sha512-wKRCQ27xCUJx5d6IivfjYGq8oVngqIhlhSAJntgXLt7Uo9sRT/3EppMHqUZRfyuNBTbykEre1s5166z+pvRB5A==
|
integrity sha512-krT+2G3kEsEUvZoYte3/2IscscDraYPc2B+fDJFipPktJmrv088Pei/RjrhWm5TMIy5URYjZUoDZdh5k940Dyw==
|
||||||
|
|
||||||
"@next/swc-linux-x64-gnu@13.4.2":
|
"@next/swc-linux-x64-gnu@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.2.tgz#0241dc011d73f08df9d9998cffdfcf08d1971520"
|
resolved "https://registry.npmmirror.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.3.tgz#3f85bc5591c6a0d4908404f7e88e3c04f4462039"
|
||||||
integrity sha512-NpCa+UVhhuNeaFVUP1Bftm0uqtvLWq2JTm7+Ta48+2Uqj2mNXrDIvyn1DY/ZEfmW/1yvGBRaUAv9zkMkMRixQA==
|
integrity sha512-AMdFX6EKJjC0G/CM6hJvkY8wUjCcbdj3Qg7uAQJ7PVejRWaVt0sDTMavbRfgMchx8h8KsAudUCtdFkG9hlEClw==
|
||||||
|
|
||||||
"@next/swc-linux-x64-musl@13.4.2":
|
"@next/swc-linux-x64-musl@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.2.tgz#fd35919e2b64b1c739583145799fefd594ef5d63"
|
resolved "https://registry.npmmirror.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.3.tgz#f4535adc2374a86bc8e43af149b551567df065de"
|
||||||
integrity sha512-ZWVC72x0lW4aj44e3khvBrj2oSYj1bD0jESmyah3zG/3DplEy/FOtYkMzbMjHTdDSheso7zH8GIlW6CDQnKhmQ==
|
integrity sha512-jySgSXE48shaLtcQbiFO9ajE9mqz7pcAVLnVLvRIlUHyQYR/WyZdK8ehLs65Mz6j9cLrJM+YdmdJPyV4WDaz2g==
|
||||||
|
|
||||||
"@next/swc-win32-arm64-msvc@13.4.2":
|
"@next/swc-win32-arm64-msvc@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.2.tgz#fa95d2dbb97707c130a868a1bd7e83e64bedf4c6"
|
resolved "https://registry.npmmirror.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.3.tgz#e76106d85391c308c5ed70cda2bca2c582d65536"
|
||||||
integrity sha512-pLT+OWYpzJig5K4VKhLttlIfBcVZfr2+Xbjra0Tjs83NQSkFS+y7xx+YhCwvpEmXYLIvaggj2ONPyjbiigOvHQ==
|
integrity sha512-5DxHo8uYcaADiE9pHrg8o28VMt/1kR8voDehmfs9AqS0qSClxAAl+CchjdboUvbCjdNWL1MISCvEfKY2InJ3JA==
|
||||||
|
|
||||||
"@next/swc-win32-ia32-msvc@13.4.2":
|
"@next/swc-win32-ia32-msvc@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.2.tgz#31a98e61d3cda92ec2293c50df7cb5280fc63697"
|
resolved "https://registry.npmmirror.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.3.tgz#8eb5d9dd71ed7a971671291605ad64ad522fb3bc"
|
||||||
integrity sha512-dhpiksQCyGca4WY0fJyzK3FxMDFoqMb0Cn+uDB+9GYjpU2K5//UGPQlCwiK4JHxuhg8oLMag5Nf3/IPSJNG8jw==
|
integrity sha512-LaqkF3d+GXRA5X6zrUjQUrXm2MN/3E2arXBtn5C7avBCNYfm9G3Xc646AmmmpN3DJZVaMYliMyCIQCMDEzk80w==
|
||||||
|
|
||||||
"@next/swc-win32-x64-msvc@13.4.2":
|
"@next/swc-win32-x64-msvc@13.4.3":
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.2.tgz#8435ab6087046355f5de07122d3097949e8fab10"
|
resolved "https://registry.npmmirror.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.3.tgz#c7b2b1b9e158fd7749f8209e68ee8e43a997eb4c"
|
||||||
integrity sha512-O7bort1Vld00cu8g0jHZq3cbSTUNMohOEvYqsqE10+yfohhdPHzvzO+ziJRz4Dyyr/fYKREwS7gR4JC0soSOMw==
|
integrity sha512-jglUk/x7ZWeOJWlVoKyIAkHLTI+qEkOriOOV+3hr1GyiywzcqfI7TpFSiwC7kk1scOiH7NTFKp8mA3XPNO9bDw==
|
||||||
|
|
||||||
"@nodelib/fs.scandir@2.1.5":
|
"@nodelib/fs.scandir@2.1.5":
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
@ -4275,12 +4275,12 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
||||||
|
|
||||||
next@^13.4.2:
|
next@^13.4.3:
|
||||||
version "13.4.2"
|
version "13.4.3"
|
||||||
resolved "https://registry.npmmirror.com/next/-/next-13.4.2.tgz#972f73a794f2c61729facedc79c49b22bdc89f0c"
|
resolved "https://registry.npmmirror.com/next/-/next-13.4.3.tgz#7f417dec9fa2731d8c1d1819a1c7d0919ad6fc75"
|
||||||
integrity sha512-aNFqLs3a3nTGvLWlO9SUhCuMUHVPSFQC0+tDNGAsDXqx+WJDFSbvc233gOJ5H19SBc7nw36A9LwQepOJ2u/8Kg==
|
integrity sha512-FV3pBrAAnAIfOclTvncw9dDohyeuEEXPe5KNcva91anT/rdycWbgtu3IjUj4n5yHnWK8YEPo0vrUecHmnmUNbA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@next/env" "13.4.2"
|
"@next/env" "13.4.3"
|
||||||
"@swc/helpers" "0.5.1"
|
"@swc/helpers" "0.5.1"
|
||||||
busboy "1.6.0"
|
busboy "1.6.0"
|
||||||
caniuse-lite "^1.0.30001406"
|
caniuse-lite "^1.0.30001406"
|
||||||
@ -4288,15 +4288,15 @@ next@^13.4.2:
|
|||||||
styled-jsx "5.1.1"
|
styled-jsx "5.1.1"
|
||||||
zod "3.21.4"
|
zod "3.21.4"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@next/swc-darwin-arm64" "13.4.2"
|
"@next/swc-darwin-arm64" "13.4.3"
|
||||||
"@next/swc-darwin-x64" "13.4.2"
|
"@next/swc-darwin-x64" "13.4.3"
|
||||||
"@next/swc-linux-arm64-gnu" "13.4.2"
|
"@next/swc-linux-arm64-gnu" "13.4.3"
|
||||||
"@next/swc-linux-arm64-musl" "13.4.2"
|
"@next/swc-linux-arm64-musl" "13.4.3"
|
||||||
"@next/swc-linux-x64-gnu" "13.4.2"
|
"@next/swc-linux-x64-gnu" "13.4.3"
|
||||||
"@next/swc-linux-x64-musl" "13.4.2"
|
"@next/swc-linux-x64-musl" "13.4.3"
|
||||||
"@next/swc-win32-arm64-msvc" "13.4.2"
|
"@next/swc-win32-arm64-msvc" "13.4.3"
|
||||||
"@next/swc-win32-ia32-msvc" "13.4.2"
|
"@next/swc-win32-ia32-msvc" "13.4.3"
|
||||||
"@next/swc-win32-x64-msvc" "13.4.2"
|
"@next/swc-win32-x64-msvc" "13.4.3"
|
||||||
|
|
||||||
node-domexception@^1.0.0:
|
node-domexception@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user