Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…-Web into chatgpt-main
  • Loading branch information
Kosette committed May 14, 2024
2 parents af20eee + cf635a5 commit ffe5605
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 134 deletions.
12 changes: 7 additions & 5 deletions app/api/webdav/[...path]/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { NextRequest, NextResponse } from "next/server";
import { STORAGE_KEY, internalWhiteWebDavEndpoints } from "../../../constant";
import { STORAGE_KEY, internalAllowedWebDavEndpoints } from "../../../constant";
import { getServerSideConfig } from "@/app/config/server";

const config = getServerSideConfig();

const mergedWhiteWebDavEndpoints = [
...internalWhiteWebDavEndpoints,
...config.whiteWebDevEndpoints,
const mergedAllowedWebDavEndpoints = [
...internalAllowedWebDavEndpoints,
...config.allowedWebDevEndpoints,
].filter((domain) => Boolean(domain.trim()));

async function handle(
Expand All @@ -24,7 +24,9 @@ async function handle(

// Validate the endpoint to prevent potential SSRF attacks
if (
!mergedWhiteWebDavEndpoints.some((white) => endpoint?.startsWith(white))
!mergedAllowedWebDavEndpoints.some(
(allowedEndpoint) => endpoint?.startsWith(allowedEndpoint),
)
) {
return NextResponse.json(
{
Expand Down
7 changes: 7 additions & 0 deletions app/client/platforms/anthropic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ export class ClaudeApi implements LLMApi {
};
});

if (prompt[0]?.role === "assistant") {
prompt.unshift({
role: "user",
content: ";",
});
}

const requestBody: AnthropicChatRequest = {
messages: prompt,
stream: shouldStream,
Expand Down
1 change: 1 addition & 0 deletions app/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,7 @@ function _Chat() {
if (payload.url) {
accessStore.update((access) => (access.openaiUrl = payload.url!));
}
accessStore.update((access) => (access.useCustomConfig = true));
});
}
} catch {
Expand Down
46 changes: 31 additions & 15 deletions app/config/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => {
if (typeof process === "undefined") {
throw Error(
Expand All @@ -74,34 +90,34 @@ export const getServerSideConfig = () => {
const isGoogle = !!process.env.GOOGLE_API_KEY;
const isAnthropic = !!process.env.ANTHROPIC_API_KEY;

const apiKeyEnvVar = process.env.OPENAI_API_KEY ?? "";
const apiKeys = apiKeyEnvVar.split(",").map((v) => v.trim());
const randomIndex = Math.floor(Math.random() * apiKeys.length);
const apiKey = apiKeys[randomIndex];
console.log(
`[Server Config] using ${randomIndex + 1} of ${apiKeys.length} api key`,
);
// const apiKeyEnvVar = process.env.OPENAI_API_KEY ?? "";
// const apiKeys = apiKeyEnvVar.split(",").map((v) => v.trim());
// const randomIndex = Math.floor(Math.random() * apiKeys.length);
// const apiKey = apiKeys[randomIndex];
// console.log(
// `[Server Config] using ${randomIndex + 1} of ${apiKeys.length} api key`,
// );

const whiteWebDevEndpoints = (process.env.WHITE_WEBDEV_ENDPOINTS ?? "").split(
",",
);
const allowedWebDevEndpoints = (
process.env.WHITE_WEBDEV_ENDPOINTS ?? ""
).split(",");

return {
baseUrl: process.env.BASE_URL,
apiKey,
apiKey: getApiKey(process.env.OPENAI_API_KEY),
openaiOrgId: process.env.OPENAI_ORG_ID,

isAzure,
azureUrl: process.env.AZURE_URL,
azureApiKey: process.env.AZURE_API_KEY,
azureApiKey: getApiKey(process.env.AZURE_API_KEY),
azureApiVersion: process.env.AZURE_API_VERSION,

isGoogle,
googleApiKey: process.env.GOOGLE_API_KEY,
googleApiKey: getApiKey(process.env.GOOGLE_API_KEY),
googleUrl: process.env.GOOGLE_URL,

isAnthropic,
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
anthropicApiKey: getApiKey(process.env.ANTHROPIC_API_KEY),
anthropicApiVersion: process.env.ANTHROPIC_API_VERSION,
anthropicUrl: process.env.ANTHROPIC_URL,

Expand All @@ -120,6 +136,6 @@ export const getServerSideConfig = () => {
disableFastLink: !!process.env.DISABLE_FAST_LINK,
customModels,
defaultModel,
whiteWebDevEndpoints,
allowedWebDevEndpoints,
};
};
8 changes: 6 additions & 2 deletions app/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ export const KnowledgeCutOffDate: Record<string, string> = {
"gpt-4-turbo": "2023-12",
"gpt-4-turbo-2024-04-09": "2023-12",
"gpt-4-turbo-preview": "2023-12",
"gpt-4o": "2023-10",
"gpt-4o-2024-05-13": "2023-10",
"gpt-4-vision-preview": "2023-04",
// After improvements,
// it's now easier to add "KnowledgeCutOffDate" instead of stupid hardcoding it, as was done previously.
Expand All @@ -144,8 +146,10 @@ const openaiModels = [
"gpt-4-32k-0613",
"gpt-4-turbo",
"gpt-4-turbo-preview",
"gpt-4o",
"gpt-4o-2024-05-13",
"gpt-4-vision-preview",
"gpt-4-turbo-2024-04-09",
"gpt-4-turbo-2024-04-09"
];

const googleModels = [
Expand Down Expand Up @@ -197,7 +201,7 @@ export const CHAT_PAGE_SIZE = 15;
export const MAX_RENDER_MSG_COUNT = 45;

// some famous webdav endpoints
export const internalWhiteWebDavEndpoints = [
export const internalAllowedWebDavEndpoints = [
"https://dav.jianguoyun.com/dav/",
"https://dav.dropdav.com/",
"https://dav.box.com/dav",
Expand Down
2 changes: 1 addition & 1 deletion app/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ const en: LocaleType = {

Endpoint: {
Title: "OpenAI Endpoint",
SubTitle: "Must starts with http(s):// or use /api/openai as default",
SubTitle: "Must start with http(s):// or use /api/openai as default",
},
},
Azure: {
Expand Down
16 changes: 14 additions & 2 deletions app/store/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { estimateTokenLength } from "../utils/token";
import { nanoid } from "nanoid";
import { createPersistStore } from "../utils/store";
import { identifyDefaultClaudeModel } from "../utils/checkers";
import { collectModelsWithDefaultModel } from "../utils/model";
import { useAccessStore } from "./access";

export type ChatMessage = RequestMessage & {
date: string;
Expand Down Expand Up @@ -87,9 +89,19 @@ function createEmptySession(): ChatSession {
function getSummarizeModel(currentModel: string) {
// if it is using gpt-* models, force to use 3.5 to summarize
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 currentModel;
Expand Down
17 changes: 12 additions & 5 deletions app/store/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,18 @@ export const useSyncStore = createPersistStore(
const client = this.getClient();

try {
const remoteState = JSON.parse(
await client.get(config.username),
) as AppState;
mergeAppState(localState, remoteState);
setLocalAppState(localState);
const remoteState = await client.get(config.username);
if (!remoteState || remoteState === "") {
await client.set(config.username, JSON.stringify(localState));
console.log("[Sync] Remote state is empty, using local state instead.");
return
} else {
const parsedRemoteState = JSON.parse(
await client.get(config.username),
) as AppState;
mergeAppState(localState, parsedRemoteState);
setLocalAppState(localState);
}
} catch (e) {
console.log("[Sync] failed to get remote state", e);
throw e;
Expand Down
13 changes: 7 additions & 6 deletions app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,16 +290,17 @@ export function getMessageImages(message: RequestMessage): string[] {
}

export function isVisionModel(model: string) {

// Note: This is a better way using the TypeScript feature instead of `&&` or `||` (ts v5.5.0-dev.20240314 I've been using)

const visionKeywords = [
"vision",
"claude-3",
"gemini-1.5-pro",
"gpt-4-turbo",
"gpt-4o",
];
const isGpt4TurboPreview = model === "gpt-4-turbo-preview";

const isGpt4Turbo = model.includes("gpt-4-turbo") && !model.includes("preview");

return visionKeywords.some((keyword) => model.includes(keyword)) || isGpt4Turbo;
return (
visionKeywords.some((keyword) => model.includes(keyword)) &&
!isGpt4TurboPreview
);
}
5 changes: 1 addition & 4 deletions app/utils/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,10 @@ export function collectModelTableWithDefaultModel(
) {
let modelTable = collectModelTable(models, customModels);
if (defaultModel && defaultModel !== "") {
delete modelTable[defaultModel];
modelTable[defaultModel] = {
...modelTable[defaultModel],
name: defaultModel,
displayName: defaultModel,
available: true,
provider:
modelTable[defaultModel]?.provider ?? customProvider(defaultModel),
isDefault: true,
};
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"html-to-image": "^1.11.11",
"mermaid": "^10.6.1",
"nanoid": "^5.0.3",
"next": "^13.4.9",
"next": "^14.1.1",
"node-fetch": "^3.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"package": {
"productName": "NextChat",
"version": "2.12.2"
"version": "2.12.3"
},
"tauri": {
"allowlist": {
Expand Down Expand Up @@ -112,4 +112,4 @@
}
]
}
}
}
Loading

0 comments on commit ffe5605

Please sign in to comment.