mirror of
https://github.com/Yidadaa/ChatGPT-Next-Web.git
synced 2025-09-01 12:46:58 +08:00
Compare commits
8 Commits
v2.12.1
...
feat/deeps
Author | SHA1 | Date | |
---|---|---|---|
|
27ac18d9d7 | ||
|
3513c6801e | ||
|
864529cbf6 | ||
|
58c0d3e12d | ||
|
a1493bfb4e | ||
|
b3e856df1d | ||
|
52312dbd23 | ||
|
b2e8a1eaa2 |
@@ -54,10 +54,11 @@ ANTHROPIC_API_KEY=
|
|||||||
### anthropic claude Api version. (optional)
|
### anthropic claude Api version. (optional)
|
||||||
ANTHROPIC_API_VERSION=
|
ANTHROPIC_API_VERSION=
|
||||||
|
|
||||||
|
# deepseek api key (optional)
|
||||||
|
DEEPSEEK_API_KEY=
|
||||||
|
|
||||||
### anthropic claude Api url (optional)
|
### anthropic claude Api url (optional)
|
||||||
ANTHROPIC_URL=
|
ANTHROPIC_URL=
|
||||||
|
|
||||||
### (optional)
|
### (optional)
|
||||||
WHITE_WEBDEV_ENDPOINTS=
|
WEBDEV_ENDPOINTS_WHITELIST=
|
11
README.md
11
README.md
@@ -212,6 +212,10 @@ anthropic claude Api version.
|
|||||||
|
|
||||||
anthropic claude Api Url.
|
anthropic claude Api Url.
|
||||||
|
|
||||||
|
### `DEEPSEEK_API_KEY` (optional)
|
||||||
|
|
||||||
|
deepseek Api Key.
|
||||||
|
|
||||||
### `HIDE_USER_API_KEY` (optional)
|
### `HIDE_USER_API_KEY` (optional)
|
||||||
|
|
||||||
> Default: Empty
|
> Default: Empty
|
||||||
@@ -245,11 +249,12 @@ To control custom models, use `+` to add a custom model, use `-` to hide a model
|
|||||||
|
|
||||||
User `-all` to disable all default models, `+all` to enable all default models.
|
User `-all` to disable all default models, `+all` to enable all default models.
|
||||||
|
|
||||||
### `WHITE_WEBDEV_ENDPOINTS` (可选)
|
### `WEBDEV_ENDPOINTS_WHITELIST` (可选)
|
||||||
|
|
||||||
You can use this option if you want to increase the number of webdav service addresses you are allowed to access, as required by the format:
|
You can use this option if you want to increase the number of webdav service addresses you are allowed to access, as required by the format:
|
||||||
- Each address must be a complete endpoint
|
|
||||||
> `https://xxxx/yyy`
|
- Each address must be a complete endpoint
|
||||||
|
> `https://xxxx/yyy`
|
||||||
- Multiple addresses are connected by ', '
|
- Multiple addresses are connected by ', '
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
@@ -126,6 +126,10 @@ anthropic claude Api version.
|
|||||||
|
|
||||||
anthropic claude Api Url.
|
anthropic claude Api Url.
|
||||||
|
|
||||||
|
### `DEEPSEEK_API_KEY` (optional)
|
||||||
|
|
||||||
|
deepseek Api Key.
|
||||||
|
|
||||||
### `HIDE_USER_API_KEY` (可选)
|
### `HIDE_USER_API_KEY` (可选)
|
||||||
|
|
||||||
如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。
|
如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。
|
||||||
@@ -142,11 +146,12 @@ anthropic claude Api Url.
|
|||||||
|
|
||||||
如果你想禁用从链接解析预制设置,将此环境变量设置为 1 即可。
|
如果你想禁用从链接解析预制设置,将此环境变量设置为 1 即可。
|
||||||
|
|
||||||
### `WHITE_WEBDEV_ENDPOINTS` (可选)
|
### `WEBDEV_ENDPOINTS_WHITELIST` (可选)
|
||||||
|
|
||||||
如果你想增加允许访问的webdav服务地址,可以使用该选项,格式要求:
|
如果你想增加允许访问的webdav服务地址,可以使用该选项,格式要求:
|
||||||
|
|
||||||
- 每一个地址必须是一个完整的 endpoint
|
- 每一个地址必须是一个完整的 endpoint
|
||||||
> `https://xxxx/xxx`
|
> `https://xxxx/xxx`
|
||||||
- 多个地址以`,`相连
|
- 多个地址以`,`相连
|
||||||
|
|
||||||
### `CUSTOM_MODELS` (可选)
|
### `CUSTOM_MODELS` (可选)
|
||||||
|
@@ -73,6 +73,10 @@ export function auth(req: NextRequest, modelProvider: ModelProvider) {
|
|||||||
case ModelProvider.Claude:
|
case ModelProvider.Claude:
|
||||||
systemApiKey = serverConfig.anthropicApiKey;
|
systemApiKey = serverConfig.anthropicApiKey;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ModelProvider.Deepseek:
|
||||||
|
systemApiKey = serverConfig.deepseekApiKey;
|
||||||
|
break;
|
||||||
case ModelProvider.GPT:
|
case ModelProvider.GPT:
|
||||||
default:
|
default:
|
||||||
if (serverConfig.isAzure) {
|
if (serverConfig.isAzure) {
|
||||||
|
@@ -87,6 +87,8 @@ export async function requestOpenai(req: NextRequest) {
|
|||||||
DEFAULT_MODELS,
|
DEFAULT_MODELS,
|
||||||
serverConfig.customModels,
|
serverConfig.customModels,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// check if deepseek model
|
||||||
const clonedBody = await req.text();
|
const clonedBody = await req.text();
|
||||||
fetchOptions.body = clonedBody;
|
fetchOptions.body = clonedBody;
|
||||||
|
|
||||||
@@ -112,16 +114,16 @@ export async function requestOpenai(req: NextRequest) {
|
|||||||
try {
|
try {
|
||||||
const res = await fetch(fetchUrl, fetchOptions);
|
const res = await fetch(fetchUrl, fetchOptions);
|
||||||
|
|
||||||
// Extract the OpenAI-Organization header from the response
|
// Extract the OpenAI-Organization header from the response
|
||||||
const openaiOrganizationHeader = res.headers.get("OpenAI-Organization");
|
const openaiOrganizationHeader = res.headers.get("OpenAI-Organization");
|
||||||
|
|
||||||
// Check if serverConfig.openaiOrgId is defined and not an empty string
|
// Check if serverConfig.openaiOrgId is defined and not an empty string
|
||||||
if (serverConfig.openaiOrgId && serverConfig.openaiOrgId.trim() !== "") {
|
if (serverConfig.openaiOrgId && serverConfig.openaiOrgId.trim() !== "") {
|
||||||
// If openaiOrganizationHeader is present, log it; otherwise, log that the header is not present
|
// If openaiOrganizationHeader is present, log it; otherwise, log that the header is not present
|
||||||
console.log("[Org ID]", openaiOrganizationHeader);
|
console.log("[Org ID]", openaiOrganizationHeader);
|
||||||
} else {
|
} else {
|
||||||
console.log("[Org ID] is not set up.");
|
console.log("[Org ID] is not set up.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// to prevent browser prompt for credentials
|
// to prevent browser prompt for credentials
|
||||||
const newHeaders = new Headers(res.headers);
|
const newHeaders = new Headers(res.headers);
|
||||||
@@ -129,7 +131,6 @@ export async function requestOpenai(req: NextRequest) {
|
|||||||
// to disable nginx buffering
|
// to disable nginx buffering
|
||||||
newHeaders.set("X-Accel-Buffering", "no");
|
newHeaders.set("X-Accel-Buffering", "no");
|
||||||
|
|
||||||
|
|
||||||
// Conditionally delete the OpenAI-Organization header from the response if [Org ID] is undefined or empty (not setup in ENV)
|
// Conditionally delete the OpenAI-Organization header from the response if [Org ID] is undefined or empty (not setup in ENV)
|
||||||
// Also, this is to prevent the header from being sent to the client
|
// Also, this is to prevent the header from being sent to the client
|
||||||
if (!serverConfig.openaiOrgId || serverConfig.openaiOrgId.trim() === "") {
|
if (!serverConfig.openaiOrgId || serverConfig.openaiOrgId.trim() === "") {
|
||||||
@@ -142,7 +143,6 @@ export async function requestOpenai(req: NextRequest) {
|
|||||||
// The browser will try to decode the response with brotli and fail
|
// The browser will try to decode the response with brotli and fail
|
||||||
newHeaders.delete("content-encoding");
|
newHeaders.delete("content-encoding");
|
||||||
|
|
||||||
|
|
||||||
return new Response(res.body, {
|
return new Response(res.body, {
|
||||||
status: res.status,
|
status: res.status,
|
||||||
statusText: res.statusText,
|
statusText: res.statusText,
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { STORAGE_KEY, internalWhiteWebDavEndpoints } from "../../../constant";
|
import { STORAGE_KEY, internalAllowedWebDavEndpoints } from "../../../constant";
|
||||||
import { getServerSideConfig } from "@/app/config/server";
|
import { getServerSideConfig } from "@/app/config/server";
|
||||||
|
|
||||||
const config = getServerSideConfig();
|
const config = getServerSideConfig();
|
||||||
|
|
||||||
const mergedWhiteWebDavEndpoints = [
|
const mergedAllowedWebDavEndpoints = [
|
||||||
...internalWhiteWebDavEndpoints,
|
...internalAllowedWebDavEndpoints,
|
||||||
...config.whiteWebDevEndpoints,
|
...config.allowedWebDevEndpoints,
|
||||||
].filter((domain) => Boolean(domain.trim()));
|
].filter((domain) => Boolean(domain.trim()));
|
||||||
|
|
||||||
async function handle(
|
async function handle(
|
||||||
@@ -24,7 +24,9 @@ async function handle(
|
|||||||
|
|
||||||
// Validate the endpoint to prevent potential SSRF attacks
|
// Validate the endpoint to prevent potential SSRF attacks
|
||||||
if (
|
if (
|
||||||
!mergedWhiteWebDavEndpoints.some((white) => endpoint?.startsWith(white))
|
!mergedAllowedWebDavEndpoints.some(
|
||||||
|
(allowedEndpoint) => endpoint?.startsWith(allowedEndpoint),
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
|
@@ -70,7 +70,7 @@ export abstract class LLMApi {
|
|||||||
abstract models(): Promise<LLMModel[]>;
|
abstract models(): Promise<LLMModel[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProviderName = "openai" | "azure" | "claude" | "palm";
|
type ProviderName = "openai" | "azure" | "claude" | "palm" | "deepseek";
|
||||||
|
|
||||||
interface Model {
|
interface Model {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -162,6 +162,7 @@ export function getHeaders() {
|
|||||||
const modelConfig = useChatStore.getState().currentSession().mask.modelConfig;
|
const modelConfig = useChatStore.getState().currentSession().mask.modelConfig;
|
||||||
const isGoogle = modelConfig.model.startsWith("gemini");
|
const isGoogle = modelConfig.model.startsWith("gemini");
|
||||||
const isAzure = accessStore.provider === ServiceProvider.Azure;
|
const isAzure = accessStore.provider === ServiceProvider.Azure;
|
||||||
|
const isDeepSeek = accessStore.provider === ServiceProvider.DeepSeek;
|
||||||
const authHeader = isAzure ? "api-key" : "Authorization";
|
const authHeader = isAzure ? "api-key" : "Authorization";
|
||||||
const apiKey = isGoogle
|
const apiKey = isGoogle
|
||||||
? accessStore.googleApiKey
|
? accessStore.googleApiKey
|
||||||
|
@@ -161,6 +161,13 @@ export class ClaudeApi implements LLMApi {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (prompt[0]?.role === "assistant") {
|
||||||
|
prompt.unshift({
|
||||||
|
role: "user",
|
||||||
|
content: ";",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const requestBody: AnthropicChatRequest = {
|
const requestBody: AnthropicChatRequest = {
|
||||||
messages: prompt,
|
messages: prompt,
|
||||||
stream: shouldStream,
|
stream: shouldStream,
|
||||||
|
@@ -1088,6 +1088,7 @@ function _Chat() {
|
|||||||
if (payload.url) {
|
if (payload.url) {
|
||||||
accessStore.update((access) => (access.openaiUrl = payload.url!));
|
accessStore.update((access) => (access.openaiUrl = payload.url!));
|
||||||
}
|
}
|
||||||
|
accessStore.update((access) => (access.useCustomConfig = true));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
@@ -51,6 +51,22 @@ const ACCESS_CODES = (function getAccessCodes(): Set<string> {
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function getApiKey(keys?: string) {
|
||||||
|
const apiKeyEnvVar = keys ?? "";
|
||||||
|
const apiKeys = apiKeyEnvVar.split(",").map((v) => v.trim());
|
||||||
|
const randomIndex = Math.floor(Math.random() * apiKeys.length);
|
||||||
|
const apiKey = apiKeys[randomIndex];
|
||||||
|
if (apiKey) {
|
||||||
|
console.log(
|
||||||
|
`[Server Config] using ${randomIndex + 1} of ${
|
||||||
|
apiKeys.length
|
||||||
|
} api key - ${apiKey}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
export const getServerSideConfig = () => {
|
export const getServerSideConfig = () => {
|
||||||
if (typeof process === "undefined") {
|
if (typeof process === "undefined") {
|
||||||
throw Error(
|
throw Error(
|
||||||
@@ -73,38 +89,41 @@ export const getServerSideConfig = () => {
|
|||||||
const isAzure = !!process.env.AZURE_URL;
|
const isAzure = !!process.env.AZURE_URL;
|
||||||
const isGoogle = !!process.env.GOOGLE_API_KEY;
|
const isGoogle = !!process.env.GOOGLE_API_KEY;
|
||||||
const isAnthropic = !!process.env.ANTHROPIC_API_KEY;
|
const isAnthropic = !!process.env.ANTHROPIC_API_KEY;
|
||||||
|
const isDeepSeek = !!process.env.DEEPSEEK_API_KEY;
|
||||||
|
|
||||||
const apiKeyEnvVar = process.env.OPENAI_API_KEY ?? "";
|
// const apiKeyEnvVar = process.env.OPENAI_API_KEY ?? "";
|
||||||
const apiKeys = apiKeyEnvVar.split(",").map((v) => v.trim());
|
// const apiKeys = apiKeyEnvVar.split(",").map((v) => v.trim());
|
||||||
const randomIndex = Math.floor(Math.random() * apiKeys.length);
|
// const randomIndex = Math.floor(Math.random() * apiKeys.length);
|
||||||
const apiKey = apiKeys[randomIndex];
|
// const apiKey = apiKeys[randomIndex];
|
||||||
console.log(
|
// console.log(
|
||||||
`[Server Config] using ${randomIndex + 1} of ${apiKeys.length} api key`,
|
// `[Server Config] using ${randomIndex + 1} of ${apiKeys.length} api key`,
|
||||||
);
|
// );
|
||||||
|
|
||||||
const whiteWebDevEndpoints = (process.env.WHITE_WEBDEV_ENDPOINTS ?? "").split(
|
const allowedWebDevEndpoints = (
|
||||||
",",
|
process.env.WEBDEV_ENDPOINTS_WHITELIST ?? ""
|
||||||
);
|
).split(",");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
baseUrl: process.env.BASE_URL,
|
baseUrl: process.env.BASE_URL,
|
||||||
apiKey,
|
apiKey: getApiKey(process.env.OPENAI_API_KEY),
|
||||||
openaiOrgId: process.env.OPENAI_ORG_ID,
|
openaiOrgId: process.env.OPENAI_ORG_ID,
|
||||||
|
|
||||||
isAzure,
|
isAzure,
|
||||||
azureUrl: process.env.AZURE_URL,
|
azureUrl: process.env.AZURE_URL,
|
||||||
azureApiKey: process.env.AZURE_API_KEY,
|
azureApiKey: getApiKey(process.env.AZURE_API_KEY),
|
||||||
azureApiVersion: process.env.AZURE_API_VERSION,
|
azureApiVersion: process.env.AZURE_API_VERSION,
|
||||||
|
|
||||||
isGoogle,
|
isGoogle,
|
||||||
googleApiKey: process.env.GOOGLE_API_KEY,
|
googleApiKey: getApiKey(process.env.GOOGLE_API_KEY),
|
||||||
googleUrl: process.env.GOOGLE_URL,
|
googleUrl: process.env.GOOGLE_URL,
|
||||||
|
|
||||||
isAnthropic,
|
isAnthropic,
|
||||||
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
|
anthropicApiKey: getApiKey(process.env.ANTHROPIC_API_KEY),
|
||||||
anthropicApiVersion: process.env.ANTHROPIC_API_VERSION,
|
anthropicApiVersion: process.env.ANTHROPIC_API_VERSION,
|
||||||
anthropicUrl: process.env.ANTHROPIC_URL,
|
anthropicUrl: process.env.ANTHROPIC_URL,
|
||||||
|
|
||||||
|
deepseekApiKey: getApiKey(process.env.DEEPSEEK_API_KEY),
|
||||||
|
|
||||||
gtmId: process.env.GTM_ID,
|
gtmId: process.env.GTM_ID,
|
||||||
|
|
||||||
needCode: ACCESS_CODES.size > 0,
|
needCode: ACCESS_CODES.size > 0,
|
||||||
@@ -120,6 +139,6 @@ export const getServerSideConfig = () => {
|
|||||||
disableFastLink: !!process.env.DISABLE_FAST_LINK,
|
disableFastLink: !!process.env.DISABLE_FAST_LINK,
|
||||||
customModels,
|
customModels,
|
||||||
defaultModel,
|
defaultModel,
|
||||||
whiteWebDevEndpoints,
|
allowedWebDevEndpoints,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
import { Chat } from "./components/chat";
|
||||||
|
|
||||||
export const OWNER = "Yidadaa";
|
export const OWNER = "Yidadaa";
|
||||||
export const REPO = "ChatGPT-Next-Web";
|
export const REPO = "ChatGPT-Next-Web";
|
||||||
export const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
|
export const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
|
||||||
@@ -70,12 +72,14 @@ export enum ServiceProvider {
|
|||||||
Azure = "Azure",
|
Azure = "Azure",
|
||||||
Google = "Google",
|
Google = "Google",
|
||||||
Anthropic = "Anthropic",
|
Anthropic = "Anthropic",
|
||||||
|
DeepSeek = "DeepSeek",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ModelProvider {
|
export enum ModelProvider {
|
||||||
GPT = "GPT",
|
GPT = "GPT",
|
||||||
GeminiPro = "GeminiPro",
|
GeminiPro = "GeminiPro",
|
||||||
Claude = "Claude",
|
Claude = "Claude",
|
||||||
|
Deepseek = "DeepSeek",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Anthropic = {
|
export const Anthropic = {
|
||||||
@@ -136,16 +140,11 @@ export const KnowledgeCutOffDate: Record<string, string> = {
|
|||||||
|
|
||||||
const openaiModels = [
|
const openaiModels = [
|
||||||
"gpt-3.5-turbo",
|
"gpt-3.5-turbo",
|
||||||
"gpt-3.5-turbo-1106",
|
|
||||||
"gpt-3.5-turbo-0125",
|
|
||||||
"gpt-4",
|
"gpt-4",
|
||||||
"gpt-4-0613",
|
|
||||||
"gpt-4-32k",
|
"gpt-4-32k",
|
||||||
"gpt-4-32k-0613",
|
|
||||||
"gpt-4-turbo",
|
"gpt-4-turbo",
|
||||||
"gpt-4-turbo-preview",
|
"gpt-4-turbo-preview",
|
||||||
"gpt-4-vision-preview",
|
"gpt-4-vision-preview",
|
||||||
"gpt-4-turbo-2024-04-09",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const googleModels = [
|
const googleModels = [
|
||||||
@@ -163,6 +162,8 @@ const anthropicModels = [
|
|||||||
"claude-3-haiku-20240307",
|
"claude-3-haiku-20240307",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const deepseekModels = ["deepseek-chat"];
|
||||||
|
|
||||||
export const DEFAULT_MODELS = [
|
export const DEFAULT_MODELS = [
|
||||||
...openaiModels.map((name) => ({
|
...openaiModels.map((name) => ({
|
||||||
name,
|
name,
|
||||||
@@ -191,13 +192,22 @@ export const DEFAULT_MODELS = [
|
|||||||
providerType: "anthropic",
|
providerType: "anthropic",
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
|
...deepseekModels.map((name) => ({
|
||||||
|
name,
|
||||||
|
available: true,
|
||||||
|
provider: {
|
||||||
|
id: "deepseek",
|
||||||
|
providerName: "DeepSeek",
|
||||||
|
providerType: "deepseek",
|
||||||
|
},
|
||||||
|
})),
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export const CHAT_PAGE_SIZE = 15;
|
export const CHAT_PAGE_SIZE = 15;
|
||||||
export const MAX_RENDER_MSG_COUNT = 45;
|
export const MAX_RENDER_MSG_COUNT = 45;
|
||||||
|
|
||||||
// some famous webdav endpoints
|
// some famous webdav endpoints
|
||||||
export const internalWhiteWebDavEndpoints = [
|
export const internalAllowedWebDavEndpoints = [
|
||||||
"https://dav.jianguoyun.com/dav/",
|
"https://dav.jianguoyun.com/dav/",
|
||||||
"https://dav.dropdav.com/",
|
"https://dav.dropdav.com/",
|
||||||
"https://dav.box.com/dav",
|
"https://dav.box.com/dav",
|
||||||
|
@@ -21,6 +21,8 @@ import { estimateTokenLength } from "../utils/token";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { createPersistStore } from "../utils/store";
|
import { createPersistStore } from "../utils/store";
|
||||||
import { identifyDefaultClaudeModel } from "../utils/checkers";
|
import { identifyDefaultClaudeModel } from "../utils/checkers";
|
||||||
|
import { collectModelsWithDefaultModel } from "../utils/model";
|
||||||
|
import { useAccessStore } from "./access";
|
||||||
|
|
||||||
export type ChatMessage = RequestMessage & {
|
export type ChatMessage = RequestMessage & {
|
||||||
date: string;
|
date: string;
|
||||||
@@ -87,9 +89,19 @@ function createEmptySession(): ChatSession {
|
|||||||
function getSummarizeModel(currentModel: string) {
|
function getSummarizeModel(currentModel: string) {
|
||||||
// if it is using gpt-* models, force to use 3.5 to summarize
|
// if it is using gpt-* models, force to use 3.5 to summarize
|
||||||
if (currentModel.startsWith("gpt")) {
|
if (currentModel.startsWith("gpt")) {
|
||||||
return SUMMARIZE_MODEL;
|
const configStore = useAppConfig.getState();
|
||||||
|
const accessStore = useAccessStore.getState();
|
||||||
|
const allModel = collectModelsWithDefaultModel(
|
||||||
|
configStore.models,
|
||||||
|
[configStore.customModels, accessStore.customModels].join(","),
|
||||||
|
accessStore.defaultModel,
|
||||||
|
);
|
||||||
|
const summarizeModel = allModel.find(
|
||||||
|
(m) => m.name === SUMMARIZE_MODEL && m.available,
|
||||||
|
);
|
||||||
|
return summarizeModel?.name ?? currentModel;
|
||||||
}
|
}
|
||||||
if (currentModel.startsWith("gemini-pro")) {
|
if (currentModel.startsWith("gemini")) {
|
||||||
return GEMINI_SUMMARIZE_MODEL;
|
return GEMINI_SUMMARIZE_MODEL;
|
||||||
}
|
}
|
||||||
return currentModel;
|
return currentModel;
|
||||||
|
@@ -64,13 +64,10 @@ export function collectModelTableWithDefaultModel(
|
|||||||
) {
|
) {
|
||||||
let modelTable = collectModelTable(models, customModels);
|
let modelTable = collectModelTable(models, customModels);
|
||||||
if (defaultModel && defaultModel !== "") {
|
if (defaultModel && defaultModel !== "") {
|
||||||
delete modelTable[defaultModel];
|
|
||||||
modelTable[defaultModel] = {
|
modelTable[defaultModel] = {
|
||||||
|
...modelTable[defaultModel],
|
||||||
name: defaultModel,
|
name: defaultModel,
|
||||||
displayName: defaultModel,
|
|
||||||
available: true,
|
available: true,
|
||||||
provider:
|
|
||||||
modelTable[defaultModel]?.provider ?? customProvider(defaultModel),
|
|
||||||
isDefault: true,
|
isDefault: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "NextChat",
|
"productName": "NextChat",
|
||||||
"version": "2.11.3"
|
"version": "2.12.2"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
Reference in New Issue
Block a user