mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-11-19 23:43:45 +08:00
@@ -1,3 +1,4 @@
|
||||
import { handle as oauthHandler } from "../../oauth_callback";
|
||||
import { ApiPath } from "@/app/constant";
|
||||
import { NextRequest } from "next/server";
|
||||
import { handle as openaiHandler } from "../../openai";
|
||||
@@ -19,6 +20,8 @@ async function handle(
|
||||
const apiPath = `/api/${params.provider}`;
|
||||
console.log(`[${params.provider} Route] params `, params);
|
||||
switch (apiPath) {
|
||||
case ApiPath.OAuth:
|
||||
return oauthHandler(req, { params });
|
||||
case ApiPath.Azure:
|
||||
return azureHandler(req, { params });
|
||||
case ApiPath.Google:
|
||||
|
||||
70
app/api/oauth_callback.ts
Normal file
70
app/api/oauth_callback.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { redirect } from "next/navigation";
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
export async function handle(
|
||||
req: NextRequest,
|
||||
{ params }: { params: { path: string[] } },
|
||||
) {
|
||||
console.log("[SF] params ", params);
|
||||
|
||||
if (req.method === "OPTIONS") {
|
||||
return NextResponse.json({ body: "OK" }, { status: 200 });
|
||||
}
|
||||
const url = new URL(req.url);
|
||||
const queryParams = new URLSearchParams(url.search);
|
||||
const code = queryParams.get("code");
|
||||
let sfak = "";
|
||||
console.log("[SF] code ", code);
|
||||
try {
|
||||
const tokenFetch = await fetch(
|
||||
`${
|
||||
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_SF_ACCOUNT_ENDPOINT ||
|
||||
"https://account.siliconflow.cn"
|
||||
}/oauth?client_id=${
|
||||
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_CLIENT_ID
|
||||
}/api/open/oauth`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
clientId: process.env.NEXT_PUBLIC_SF_NEXT_CHAT_CLIENT_ID,
|
||||
secret: process.env.SF_NEXT_CHAT_SECRET,
|
||||
code,
|
||||
}),
|
||||
},
|
||||
);
|
||||
if (!tokenFetch.ok)
|
||||
return Response.json(
|
||||
{ status: false, message: "fetch error" },
|
||||
{ status: 500 },
|
||||
);
|
||||
const tokenJson = await tokenFetch.json();
|
||||
const access_token = tokenJson.status ? tokenJson.data?.access_token : null;
|
||||
console.log("access_token", access_token);
|
||||
// uat https://cloud-uat.siliconflow.cn
|
||||
// prod https://cloud.siliconflow.cn
|
||||
const apiKey = await fetch(
|
||||
`${
|
||||
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_SF_CLOUD_ENDPOINT ||
|
||||
"https://cloud.siliconflow.cn"
|
||||
}/api/oauth/apikeys`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `token ${access_token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
const apiKeysData = await apiKey.json();
|
||||
console.log("apiKeysData", apiKeysData);
|
||||
sfak = apiKeysData.data[0].secretKey;
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
return Response.json(
|
||||
{ status: false, message: "fetch error" },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
cookies().set("sfak", sfak);
|
||||
redirect(`/`);
|
||||
}
|
||||
@@ -59,6 +59,7 @@ import {
|
||||
DEFAULT_TOPIC,
|
||||
ModelType,
|
||||
usePluginStore,
|
||||
DEFAULT_CONFIG,
|
||||
} from "../store";
|
||||
|
||||
import {
|
||||
@@ -114,6 +115,7 @@ import { ExportMessageModal } from "./exporter";
|
||||
import { getClientConfig } from "../config/client";
|
||||
import { useAllModels } from "../utils/hooks";
|
||||
import { MultimodalContent } from "../client/api";
|
||||
import { useCookies } from "react-cookie";
|
||||
|
||||
const localStorage = safeLocalStorage();
|
||||
import { ClientApi } from "../client/api";
|
||||
@@ -1244,6 +1246,99 @@ function _Chat() {
|
||||
return session.mask.hideContext ? [] : session.mask.context.slice();
|
||||
}, [session.mask.context, session.mask.hideContext]);
|
||||
|
||||
const [cookies, setCookie, removeCookie] = useCookies(["sfak"], {
|
||||
doNotParse: true,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const sfakValue = cookies.sfak;
|
||||
|
||||
const model = "Qwen/Qwen2-7B-Instruct";
|
||||
config.update((config) => {
|
||||
const ids = [
|
||||
"stabilityai/stable-diffusion-xl-base-1.0",
|
||||
"TencentARC/PhotoMaker",
|
||||
"InstantX/InstantID",
|
||||
"stabilityai/stable-diffusion-2-1",
|
||||
"stabilityai/sd-turbo",
|
||||
"stabilityai/sdxl-turbo",
|
||||
"ByteDance/SDXL-Lightning",
|
||||
"deepseek-ai/deepseek-llm-67b-chat",
|
||||
"Qwen/Qwen1.5-14B-Chat",
|
||||
"Qwen/Qwen1.5-7B-Chat",
|
||||
"Qwen/Qwen1.5-110B-Chat",
|
||||
"Qwen/Qwen1.5-32B-Chat",
|
||||
"01-ai/Yi-1.5-6B-Chat",
|
||||
"01-ai/Yi-1.5-9B-Chat-16K",
|
||||
"01-ai/Yi-1.5-34B-Chat-16K",
|
||||
"THUDM/chatglm3-6b",
|
||||
"deepseek-ai/DeepSeek-V2-Chat",
|
||||
"THUDM/glm-4-9b-chat",
|
||||
"Qwen/Qwen2-72B-Instruct",
|
||||
"Qwen/Qwen2-7B-Instruct",
|
||||
"Qwen/Qwen2-57B-A14B-Instruct",
|
||||
"stabilityai/stable-diffusion-3-medium",
|
||||
"deepseek-ai/DeepSeek-Coder-V2-Instruct",
|
||||
"Qwen/Qwen2-1.5B-Instruct",
|
||||
"internlm/internlm2_5-7b-chat",
|
||||
"BAAI/bge-large-en-v1.5",
|
||||
"BAAI/bge-large-zh-v1.5",
|
||||
"Pro/Qwen/Qwen2-7B-Instruct",
|
||||
"Pro/Qwen/Qwen2-1.5B-Instruct",
|
||||
"Pro/Qwen/Qwen1.5-7B-Chat",
|
||||
"Pro/THUDM/glm-4-9b-chat",
|
||||
"Pro/THUDM/chatglm3-6b",
|
||||
"Pro/01-ai/Yi-1.5-9B-Chat-16K",
|
||||
"Pro/01-ai/Yi-1.5-6B-Chat",
|
||||
"Pro/internlm/internlm2_5-7b-chat",
|
||||
"black-forest-labs/FLUX.1-schnell",
|
||||
"FunAudioLLM/SenseVoiceSmall",
|
||||
"netease-youdao/bce-embedding-base_v1",
|
||||
"BAAI/bge-m3",
|
||||
"internlm/internlm2_5-20b-chat",
|
||||
"Qwen/Qwen2-Math-72B-Instruct",
|
||||
"netease-youdao/bce-reranker-base_v1",
|
||||
"BAAI/bge-reranker-v2-m3",
|
||||
"deepseek-ai/DeepSeek-V2.5",
|
||||
"Ascend/Qwen/Qwen2-72B-Instruct",
|
||||
];
|
||||
config.customModels = ids
|
||||
.sort()
|
||||
.filter(
|
||||
(id) =>
|
||||
!id.toLowerCase().includes("voice") &&
|
||||
!id.toLowerCase().includes("flux") &&
|
||||
!id.toLowerCase().includes("stability") &&
|
||||
!id.toLowerCase().includes("sdxl") &&
|
||||
!id.toLowerCase().includes("photomaker") &&
|
||||
!id.toLowerCase().includes("instantid") &&
|
||||
!id.toLowerCase().includes("bge") &&
|
||||
!id.toLowerCase().includes("bce"),
|
||||
)
|
||||
.join(","); // Filter out unwanted ids;
|
||||
config.modelConfig.model = model as ModelType;
|
||||
config.modelConfig.providerName = model as ServiceProvider;
|
||||
});
|
||||
if (sfakValue) {
|
||||
chatStore.updateCurrentSession((session) => {
|
||||
if (
|
||||
session.mask.modelConfig.model == DEFAULT_CONFIG.modelConfig.model
|
||||
) {
|
||||
session.mask.modelConfig.model = model as ModelType;
|
||||
session.mask.modelConfig.providerName = model as ServiceProvider;
|
||||
}
|
||||
});
|
||||
accessStore.update((access) => {
|
||||
console.log("update access store with SF API key");
|
||||
access.useCustomConfig = true;
|
||||
access.openaiApiKey = sfakValue;
|
||||
access.openaiUrl =
|
||||
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_SF_API_ENDPOINT!;
|
||||
});
|
||||
removeCookie("sfak");
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (
|
||||
context.length === 0 &&
|
||||
session.messages.at(0)?.content !== BOT_HELLO.content
|
||||
|
||||
@@ -5,6 +5,8 @@ import styles from "./home.module.scss";
|
||||
import { IconButton } from "./button";
|
||||
import SettingsIcon from "../icons/settings.svg";
|
||||
import GithubIcon from "../icons/github.svg";
|
||||
import SiliconFlowIcon from "../icons/sf.svg";
|
||||
import SiliconFlowActiveIcon from "../icons/sf.active.svg";
|
||||
import ChatGptIcon from "../icons/chatgpt.svg";
|
||||
import AddIcon from "../icons/add.svg";
|
||||
import DeleteIcon from "../icons/delete.svg";
|
||||
@@ -14,7 +16,12 @@ import DiscoveryIcon from "../icons/discovery.svg";
|
||||
|
||||
import Locale from "../locales";
|
||||
|
||||
import { useAppConfig, useChatStore } from "../store";
|
||||
import {
|
||||
DEFAULT_CONFIG,
|
||||
useAccessStore,
|
||||
useAppConfig,
|
||||
useChatStore,
|
||||
} from "../store";
|
||||
|
||||
import {
|
||||
DEFAULT_SIDEBAR_WIDTH,
|
||||
@@ -30,6 +37,7 @@ import { Link, useNavigate } from "react-router-dom";
|
||||
import { isIOS, useMobileScreen } from "../utils";
|
||||
import dynamic from "next/dynamic";
|
||||
import { showConfirm, Selector } from "./ui-lib";
|
||||
import { useCookies } from "react-cookie";
|
||||
|
||||
const ChatList = dynamic(async () => (await import("./chat-list")).ChatList, {
|
||||
loading: () => null,
|
||||
@@ -216,6 +224,10 @@ export function SideBar(props: { className?: string }) {
|
||||
const navigate = useNavigate();
|
||||
const config = useAppConfig();
|
||||
const chatStore = useChatStore();
|
||||
const accessStore = useAccessStore();
|
||||
const [cookies, setCookie, removeCookie] = useCookies(["sfak"], {
|
||||
doNotParse: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<SideBarContainer
|
||||
@@ -307,6 +319,53 @@ export function SideBar(props: { className?: string }) {
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className={styles["sidebar-action"]}>
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
onClick={() => {
|
||||
if (accessStore.useCustomConfig && accessStore.openaiApiKey) {
|
||||
const confirmLogout = window.confirm(
|
||||
"Are you sure you want to log out?",
|
||||
);
|
||||
if (confirmLogout) {
|
||||
chatStore.updateCurrentSession((session) => {
|
||||
session.mask.modelConfig.model =
|
||||
DEFAULT_CONFIG.modelConfig.model;
|
||||
session.mask.modelConfig.providerName =
|
||||
DEFAULT_CONFIG.modelConfig.providerName;
|
||||
accessStore.update((access) => {
|
||||
removeCookie("sfak");
|
||||
access.openaiApiKey = "";
|
||||
access.useCustomConfig = false;
|
||||
window.location.href = "/";
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
window.location.href = `${
|
||||
process.env
|
||||
.NEXT_PUBLIC_SF_NEXT_CHAT_SF_ACCOUNT_ENDPOINT ||
|
||||
"https://account.siliconflow.cn"
|
||||
}/oauth?client_id=${
|
||||
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_CLIENT_ID
|
||||
}`;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
aria={Locale.Export.MessageFromChatGPT}
|
||||
key={accessStore.openaiApiKey + accessStore.openaiUrl}
|
||||
icon={
|
||||
accessStore.useCustomConfig && accessStore.openaiApiKey ? (
|
||||
<SiliconFlowActiveIcon />
|
||||
) : (
|
||||
<SiliconFlowIcon />
|
||||
)
|
||||
}
|
||||
shadow
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
secondaryAction={
|
||||
|
||||
@@ -60,6 +60,7 @@ export enum ApiPath {
|
||||
Iflytek = "/api/iflytek",
|
||||
Stability = "/api/stability",
|
||||
Artifacts = "/api/artifacts",
|
||||
OAuth = "/api/oauth_callback",
|
||||
}
|
||||
|
||||
export enum SlotID {
|
||||
@@ -230,7 +231,7 @@ You are ChatGPT, a large language model trained by {{ServiceProvider}}.
|
||||
Knowledge cutoff: {{cutoff}}
|
||||
Current model: {{model}}
|
||||
Current time: {{time}}
|
||||
Latex inline: \\(x^2\\)
|
||||
Latex inline: \\(x^2\\)
|
||||
Latex block: $$e=mc^2$$
|
||||
`;
|
||||
|
||||
|
||||
3
app/icons/sf.active.svg
Normal file
3
app/icons/sf.active.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<text x="50%" y="50%" font-family="Arial" font-size="12" fill="#6615e8" font-weight="bold" dominant-baseline="middle" text-anchor="middle">SF</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 224 B |
3
app/icons/sf.svg
Normal file
3
app/icons/sf.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<text x="50%" y="50%" font-family="Arial" font-size="12" fill="black" dominant-baseline="middle" text-anchor="middle">SF</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 203 B |
220
app/masks/cn.ts
220
app/masks/cn.ts
@@ -1,6 +1,226 @@
|
||||
import { BuiltinMask } from "./typing";
|
||||
|
||||
const mandarinExpertPrompt = `# 角色:
|
||||
你是新汉语老师,你年轻,批判现实,思考深刻,语言风趣"。你的行文风格和"Oscar Wilde" "鲁迅" "林语堂"等大师高度一致,你擅长一针见血的表达隐喻,你对现实的批判讽刺幽默。
|
||||
|
||||
- 作者:云中江树,李继刚
|
||||
- 模型:阿里通义
|
||||
|
||||
## 任务:
|
||||
将一个汉语词汇进行全新角度的解释,你会用一个特殊视角来解释一个词汇:
|
||||
用一句话表达你的词汇解释,抓住用户输入词汇的本质,使用辛辣的讽刺、一针见血的指出本质,使用包含隐喻的金句。
|
||||
例如:“委婉”: "刺向他人时, 决定在剑刃上撒上止痛药。"
|
||||
|
||||
## 输出结果:
|
||||
1. 词汇解释
|
||||
2. 输出词语卡片(Html 代码)
|
||||
- 整体设计合理使用留白,整体排版要有呼吸感
|
||||
- 设计原则:干净 简洁 纯色 典雅
|
||||
- 配色:下面的色系中随机选择一个[
|
||||
"柔和粉彩系",
|
||||
"深邃宝石系",
|
||||
"清新自然系",
|
||||
"高雅灰度系",
|
||||
"复古怀旧系",
|
||||
"明亮活力系",
|
||||
"冷淡极简系",
|
||||
"海洋湖泊系",
|
||||
"秋季丰收系",
|
||||
"莫兰迪色系"
|
||||
]
|
||||
- 卡片样式:
|
||||
(字体 . ("KaiTi, SimKai" "Arial, sans-serif"))
|
||||
(颜色 . ((背景 "#FAFAFA") (标题 "#333") (副标题 "#555") (正文 "#333")))
|
||||
(尺寸 . ((卡片宽度 "auto") (卡片高度 "auto, >宽度") (内边距 "20px")))
|
||||
(布局 . (竖版 弹性布局 居中对齐))))
|
||||
- 卡片元素:
|
||||
(标题 "汉语新解")
|
||||
(分隔线)
|
||||
(词语 用户输入)
|
||||
(拼音)
|
||||
(英文翻译)
|
||||
(日文翻译)
|
||||
(解释:(按现代诗排版))
|
||||
|
||||
## 结果示例:
|
||||
\`\`\`
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>汉语新解 - 金融杠杆</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;700&family=Noto+Sans+SC:wght@300;400&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
/* 莫兰迪色系:使用柔和、低饱和度的颜色 */
|
||||
--primary-color: #B6B5A7; /* 莫兰迪灰褐色,用于背景文字 */
|
||||
--secondary-color: #9A8F8F; /* 莫兰迪灰棕色,用于标题背景 */
|
||||
--accent-color: #C5B4A0; /* 莫兰迪淡棕色,用于强调元素 */
|
||||
--background-color: #E8E3DE; /* 莫兰迪米色,用于页面背景 */
|
||||
--text-color: #5B5B5B; /* 莫兰迪深灰色,用于主要文字 */
|
||||
--light-text-color: #8C8C8C; /* 莫兰迪中灰色,用于次要文字 */
|
||||
--divider-color: #D1CBC3; /* 莫兰迪浅灰色,用于分隔线 */
|
||||
}
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--background-color); /* 使用莫兰迪米色作为页面背景 */
|
||||
font-family: 'Noto Sans SC', sans-serif;
|
||||
color: var(--text-color); /* 使用莫兰迪深灰色作为主要文字颜色 */
|
||||
}
|
||||
.card {
|
||||
width: 300px;
|
||||
height: 500px;
|
||||
background-color: #F2EDE9; /* 莫兰迪浅米色,用于卡片背景 */
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.header {
|
||||
background-color: var(--secondary-color); /* 使用莫兰迪灰棕色作为标题背景 */
|
||||
color: #F2EDE9; /* 浅色文字与深色背景形成对比 */
|
||||
padding: 20px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
h1 {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 20px;
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
}
|
||||
.content {
|
||||
padding: 30px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.word {
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.word-main {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 36px;
|
||||
color: var(--text-color); /* 使用莫兰迪深灰色作为主要词汇颜色 */
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
.word-main::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -5px;
|
||||
width: 50px;
|
||||
height: 3px;
|
||||
background-color: var(--accent-color); /* 使用莫兰迪淡棕色作为下划线 */
|
||||
}
|
||||
.word-sub {
|
||||
font-size: 14px;
|
||||
color: var(--light-text-color); /* 使用莫兰迪中灰色作为次要文字颜色 */
|
||||
margin: 5px 0;
|
||||
}
|
||||
.divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: var(--divider-color); /* 使用莫兰迪浅灰色作为分隔线 */
|
||||
margin: 20px 0;
|
||||
}
|
||||
.explanation {
|
||||
font-size: 18px;
|
||||
line-height: 1.6;
|
||||
text-align: left;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.quote {
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
border-left: 3px solid var(--accent-color); /* 使用莫兰迪淡棕色作为引用边框 */
|
||||
}
|
||||
.background-text {
|
||||
position: absolute;
|
||||
font-size: 150px;
|
||||
color: rgba(182, 181, 167, 0.15); /* 使用莫兰迪灰褐色的透明版本作为背景文字 */
|
||||
z-index: 0;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<h1>汉语新解</h1>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="word">
|
||||
<div class="word-main">金融杠杆</div>
|
||||
<div class="word-sub">Jīn Róng Gàng Gǎn</div>
|
||||
<div class="word-sub">Financial Leverage</div>
|
||||
<div class="word-sub">金融レバレッジ</div>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="explanation">
|
||||
<div class="quote">
|
||||
<p>
|
||||
借鸡生蛋,<br>
|
||||
只不过这蛋要是金的,<br>
|
||||
鸡得赶紧卖了还债。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="background-text">杠杆</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
\`\`\`
|
||||
## 注意:
|
||||
1. 分隔线与上下元素垂直间距相同,具有分割美学。
|
||||
2. 卡片(.card)不需要 padding ,允许子元素“汉语新解”的色块完全填充到边缘,具有设计感。
|
||||
|
||||
## 初始行为:
|
||||
输出"说吧, 他们又用哪个词来忽悠你了?"`;
|
||||
export const CN_MASKS: BuiltinMask[] = [
|
||||
{
|
||||
avatar: "1f004",
|
||||
name: "汉语新解",
|
||||
context: [
|
||||
{
|
||||
id: "expert-0",
|
||||
role: "user",
|
||||
content: mandarinExpertPrompt,
|
||||
date: "",
|
||||
},
|
||||
],
|
||||
modelConfig: {
|
||||
model: "deepseek-ai/DeepSeek-Coder-V2-Instruct",
|
||||
temperature: 1,
|
||||
max_tokens: 2000,
|
||||
presence_penalty: 0,
|
||||
frequency_penalty: 0,
|
||||
sendMemory: true,
|
||||
historyMessageCount: 4,
|
||||
compressMessageLengthThreshold: 1000,
|
||||
},
|
||||
lang: "cn",
|
||||
builtin: true,
|
||||
createdAt: 1688899480511,
|
||||
},
|
||||
{
|
||||
avatar: "1f5bc-fe0f",
|
||||
name: "以文搜图",
|
||||
|
||||
@@ -615,6 +615,7 @@ export const useChatStore = createPersistStore(
|
||||
providerName,
|
||||
},
|
||||
onFinish(message) {
|
||||
if (!isValidMessage(message)) return;
|
||||
get().updateCurrentSession(
|
||||
(session) =>
|
||||
(session.topic =
|
||||
@@ -690,6 +691,10 @@ export const useChatStore = createPersistStore(
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function isValidMessage(message: any): boolean {
|
||||
return typeof message === "string" && !message.startsWith("```json");
|
||||
}
|
||||
},
|
||||
|
||||
updateStat(message: ChatMessage) {
|
||||
|
||||
Reference in New Issue
Block a user