mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-10-22 18:03:42 +08:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			97c972b21b
			...
			feat/deeps
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 27ac18d9d7 | 
| @@ -54,10 +54,11 @@ ANTHROPIC_API_KEY= | ||||
| ### anthropic claude Api version. (optional) | ||||
| ANTHROPIC_API_VERSION= | ||||
|  | ||||
|  | ||||
| # deepseek api key (optional) | ||||
| DEEPSEEK_API_KEY= | ||||
|  | ||||
| ### anthropic claude Api url (optional) | ||||
| ANTHROPIC_URL= | ||||
|  | ||||
| ### (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. | ||||
|  | ||||
| ### `DEEPSEEK_API_KEY` (optional) | ||||
|  | ||||
| deepseek Api Key. | ||||
|  | ||||
| ### `HIDE_USER_API_KEY` (optional) | ||||
|  | ||||
| > 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. | ||||
|  | ||||
| ### `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: | ||||
| - 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 ', ' | ||||
|  | ||||
| ## Requirements | ||||
|   | ||||
| @@ -126,6 +126,10 @@ anthropic claude Api version. | ||||
|  | ||||
| anthropic claude Api Url. | ||||
|  | ||||
| ### `DEEPSEEK_API_KEY` (optional) | ||||
|  | ||||
| deepseek Api Key. | ||||
|  | ||||
| ### `HIDE_USER_API_KEY` (可选) | ||||
|  | ||||
| 如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。 | ||||
| @@ -142,11 +146,12 @@ anthropic claude Api Url. | ||||
|  | ||||
| 如果你想禁用从链接解析预制设置,将此环境变量设置为 1 即可。 | ||||
|  | ||||
| ### `WHITE_WEBDEV_ENDPOINTS` (可选) | ||||
| ### `WEBDEV_ENDPOINTS_WHITELIST` (可选) | ||||
|  | ||||
| 如果你想增加允许访问的webdav服务地址,可以使用该选项,格式要求: | ||||
|  | ||||
| - 每一个地址必须是一个完整的 endpoint | ||||
| > `https://xxxx/xxx` | ||||
|   > `https://xxxx/xxx` | ||||
| - 多个地址以`,`相连 | ||||
|  | ||||
| ### `CUSTOM_MODELS` (可选) | ||||
|   | ||||
| @@ -73,6 +73,10 @@ export function auth(req: NextRequest, modelProvider: ModelProvider) { | ||||
|       case ModelProvider.Claude: | ||||
|         systemApiKey = serverConfig.anthropicApiKey; | ||||
|         break; | ||||
|  | ||||
|       case ModelProvider.Deepseek: | ||||
|         systemApiKey = serverConfig.deepseekApiKey; | ||||
|         break; | ||||
|       case ModelProvider.GPT: | ||||
|       default: | ||||
|         if (serverConfig.isAzure) { | ||||
|   | ||||
| @@ -87,6 +87,8 @@ export async function requestOpenai(req: NextRequest) { | ||||
|         DEFAULT_MODELS, | ||||
|         serverConfig.customModels, | ||||
|       ); | ||||
|  | ||||
|       // check if deepseek model | ||||
|       const clonedBody = await req.text(); | ||||
|       fetchOptions.body = clonedBody; | ||||
|  | ||||
| @@ -112,16 +114,16 @@ export async function requestOpenai(req: NextRequest) { | ||||
|   try { | ||||
|     const res = await fetch(fetchUrl, fetchOptions); | ||||
|  | ||||
|   // Extract the OpenAI-Organization header from the response | ||||
|   const openaiOrganizationHeader = res.headers.get("OpenAI-Organization"); | ||||
|     // Extract the OpenAI-Organization header from the response | ||||
|     const openaiOrganizationHeader = res.headers.get("OpenAI-Organization"); | ||||
|  | ||||
|   // Check if serverConfig.openaiOrgId is defined and not an empty string | ||||
|   if (serverConfig.openaiOrgId && serverConfig.openaiOrgId.trim() !== "") { | ||||
|     // If openaiOrganizationHeader is present, log it; otherwise, log that the header is not present | ||||
|     console.log("[Org ID]", openaiOrganizationHeader); | ||||
|   } else { | ||||
|     console.log("[Org ID] is not set up."); | ||||
|   } | ||||
|     // Check if serverConfig.openaiOrgId is defined and not an empty string | ||||
|     if (serverConfig.openaiOrgId && serverConfig.openaiOrgId.trim() !== "") { | ||||
|       // If openaiOrganizationHeader is present, log it; otherwise, log that the header is not present | ||||
|       console.log("[Org ID]", openaiOrganizationHeader); | ||||
|     } else { | ||||
|       console.log("[Org ID] is not set up."); | ||||
|     } | ||||
|  | ||||
|     // to prevent browser prompt for credentials | ||||
|     const newHeaders = new Headers(res.headers); | ||||
| @@ -129,7 +131,6 @@ export async function requestOpenai(req: NextRequest) { | ||||
|     // to disable nginx buffering | ||||
|     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) | ||||
|     // Also, this is to prevent the header from being sent to the client | ||||
|     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 | ||||
|     newHeaders.delete("content-encoding"); | ||||
|  | ||||
|  | ||||
|     return new Response(res.body, { | ||||
|       status: res.status, | ||||
|       statusText: res.statusText, | ||||
|   | ||||
| @@ -70,7 +70,7 @@ export abstract class LLMApi { | ||||
|   abstract models(): Promise<LLMModel[]>; | ||||
| } | ||||
|  | ||||
| type ProviderName = "openai" | "azure" | "claude" | "palm"; | ||||
| type ProviderName = "openai" | "azure" | "claude" | "palm" | "deepseek"; | ||||
|  | ||||
| interface Model { | ||||
|   name: string; | ||||
| @@ -162,6 +162,7 @@ export function getHeaders() { | ||||
|   const modelConfig = useChatStore.getState().currentSession().mask.modelConfig; | ||||
|   const isGoogle = modelConfig.model.startsWith("gemini"); | ||||
|   const isAzure = accessStore.provider === ServiceProvider.Azure; | ||||
|   const isDeepSeek = accessStore.provider === ServiceProvider.DeepSeek; | ||||
|   const authHeader = isAzure ? "api-key" : "Authorization"; | ||||
|   const apiKey = isGoogle | ||||
|     ? accessStore.googleApiKey | ||||
|   | ||||
| @@ -89,6 +89,7 @@ export const getServerSideConfig = () => { | ||||
|   const isAzure = !!process.env.AZURE_URL; | ||||
|   const isGoogle = !!process.env.GOOGLE_API_KEY; | ||||
|   const isAnthropic = !!process.env.ANTHROPIC_API_KEY; | ||||
|   const isDeepSeek = !!process.env.DEEPSEEK_API_KEY; | ||||
|  | ||||
|   // const apiKeyEnvVar = process.env.OPENAI_API_KEY ?? ""; | ||||
|   // const apiKeys = apiKeyEnvVar.split(",").map((v) => v.trim()); | ||||
| @@ -99,7 +100,7 @@ export const getServerSideConfig = () => { | ||||
|   // ); | ||||
|  | ||||
|   const allowedWebDevEndpoints = ( | ||||
|     process.env.WHITE_WEBDEV_ENDPOINTS ?? "" | ||||
|     process.env.WEBDEV_ENDPOINTS_WHITELIST ?? "" | ||||
|   ).split(","); | ||||
|  | ||||
|   return { | ||||
| @@ -121,6 +122,8 @@ export const getServerSideConfig = () => { | ||||
|     anthropicApiVersion: process.env.ANTHROPIC_API_VERSION, | ||||
|     anthropicUrl: process.env.ANTHROPIC_URL, | ||||
|  | ||||
|     deepseekApiKey: getApiKey(process.env.DEEPSEEK_API_KEY), | ||||
|  | ||||
|     gtmId: process.env.GTM_ID, | ||||
|  | ||||
|     needCode: ACCESS_CODES.size > 0, | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| import { Chat } from "./components/chat"; | ||||
|  | ||||
| export const OWNER = "Yidadaa"; | ||||
| export const REPO = "ChatGPT-Next-Web"; | ||||
| export const REPO_URL = `https://github.com/${OWNER}/${REPO}`; | ||||
| @@ -70,12 +72,14 @@ export enum ServiceProvider { | ||||
|   Azure = "Azure", | ||||
|   Google = "Google", | ||||
|   Anthropic = "Anthropic", | ||||
|   DeepSeek = "DeepSeek", | ||||
| } | ||||
|  | ||||
| export enum ModelProvider { | ||||
|   GPT = "GPT", | ||||
|   GeminiPro = "GeminiPro", | ||||
|   Claude = "Claude", | ||||
|   Deepseek = "DeepSeek", | ||||
| } | ||||
|  | ||||
| export const Anthropic = { | ||||
| @@ -136,16 +140,11 @@ export const KnowledgeCutOffDate: Record<string, string> = { | ||||
|  | ||||
| const openaiModels = [ | ||||
|   "gpt-3.5-turbo", | ||||
|   "gpt-3.5-turbo-1106", | ||||
|   "gpt-3.5-turbo-0125", | ||||
|   "gpt-4", | ||||
|   "gpt-4-0613", | ||||
|   "gpt-4-32k", | ||||
|   "gpt-4-32k-0613", | ||||
|   "gpt-4-turbo", | ||||
|   "gpt-4-turbo-preview", | ||||
|   "gpt-4-vision-preview", | ||||
|   "gpt-4-turbo-2024-04-09", | ||||
| ]; | ||||
|  | ||||
| const googleModels = [ | ||||
| @@ -163,6 +162,8 @@ const anthropicModels = [ | ||||
|   "claude-3-haiku-20240307", | ||||
| ]; | ||||
|  | ||||
| const deepseekModels = ["deepseek-chat"]; | ||||
|  | ||||
| export const DEFAULT_MODELS = [ | ||||
|   ...openaiModels.map((name) => ({ | ||||
|     name, | ||||
| @@ -191,6 +192,15 @@ export const DEFAULT_MODELS = [ | ||||
|       providerType: "anthropic", | ||||
|     }, | ||||
|   })), | ||||
|   ...deepseekModels.map((name) => ({ | ||||
|     name, | ||||
|     available: true, | ||||
|     provider: { | ||||
|       id: "deepseek", | ||||
|       providerName: "DeepSeek", | ||||
|       providerType: "deepseek", | ||||
|     }, | ||||
|   })), | ||||
| ] as const; | ||||
|  | ||||
| export const CHAT_PAGE_SIZE = 15; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user