This commit is contained in:
GH Action - Upstream Sync
2023-11-08 00:33:11 +00:00
16 changed files with 111 additions and 679 deletions

View File

@@ -11,6 +11,7 @@ const DANGER_CONFIG = {
hideUserApiKey: serverConfig.hideUserApiKey,
disableGPT4: serverConfig.disableGPT4,
hideBalanceQuery: serverConfig.hideBalanceQuery,
disableFastLink: serverConfig.disableFastLink,
};
declare global {

View File

@@ -12,11 +12,16 @@ import { getClientConfig } from "../config/client";
export function AuthPage() {
const navigate = useNavigate();
const access = useAccessStore();
const accessStore = useAccessStore();
const goHome = () => navigate(Path.Home);
const goChat = () => navigate(Path.Chat);
const resetAccessCode = () => { access.updateCode(""); access.updateToken(""); }; // Reset access code to empty string
const resetAccessCode = () => {
accessStore.update((access) => {
access.token = "";
access.accessCode = "";
});
}; // Reset access code to empty string
useEffect(() => {
if (getClientConfig()?.isApp) {
@@ -38,21 +43,25 @@ export function AuthPage() {
className={styles["auth-input"]}
type="password"
placeholder={Locale.Auth.Input}
value={access.accessCode}
value={accessStore.accessCode}
onChange={(e) => {
access.updateCode(e.currentTarget.value);
accessStore.update(
(access) => (access.accessCode = e.currentTarget.value),
);
}}
/>
{!access.hideUserApiKey ? (
{!accessStore.hideUserApiKey ? (
<>
<div className={styles["auth-tips"]}>{Locale.Auth.SubTips}</div>
<input
className={styles["auth-input"]}
type="password"
placeholder={Locale.Settings.Token.Placeholder}
value={access.token}
value={accessStore.token}
onChange={(e) => {
access.updateToken(e.currentTarget.value);
accessStore.update(
(access) => (access.token = e.currentTarget.value),
);
}}
/>
</>

View File

@@ -73,11 +73,10 @@ import {
showPrompt,
showToast,
} from "./ui-lib";
import { useLocation, useNavigate } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import {
CHAT_PAGE_SIZE,
LAST_INPUT_KEY,
MAX_RENDER_MSG_COUNT,
Path,
REQUEST_TIMEOUT_MS,
UNFINISHED_INPUT,
@@ -976,14 +975,17 @@ function _Chat() {
doSubmit(text);
},
code: (text) => {
if (accessStore.disableFastLink) return;
console.log("[Command] got code from url: ", text);
showConfirm(Locale.URLCommand.Code + `code = ${text}`).then((res) => {
if (res) {
accessStore.updateCode(text);
accessStore.update((access) => (access.accessCode = text));
}
});
},
settings: (text) => {
if (accessStore.disableFastLink) return;
try {
const payload = JSON.parse(text) as {
key?: string;
@@ -999,10 +1001,10 @@ function _Chat() {
).then((res) => {
if (!res) return;
if (payload.key) {
accessStore.updateToken(payload.key);
accessStore.update((access) => (access.token = payload.key!));
}
if (payload.url) {
accessStore.updateOpenAiUrl(payload.url);
accessStore.update((access) => (access.openaiUrl = payload.url!));
}
});
}

View File

@@ -50,7 +50,13 @@ import Locale, {
} from "../locales";
import { copyToClipboard } from "../utils";
import Link from "next/link";
import { Path, RELEASE_URL, STORAGE_KEY, UPDATE_URL } from "../constant";
import {
OPENAI_BASE_URL,
Path,
RELEASE_URL,
STORAGE_KEY,
UPDATE_URL,
} from "../constant";
import { Prompt, SearchService, usePromptStore } from "../store/prompt";
import { ErrorBoundary } from "./error";
import { InputRange } from "./input-range";
@@ -571,13 +577,19 @@ export function Settings() {
console.log("[Update] remote version ", updateStore.remoteVersion);
}
const accessStore = useAccessStore();
const shouldHideBalanceQuery = useMemo(() => {
const isOpenAiUrl = accessStore.openaiUrl.includes(OPENAI_BASE_URL);
return accessStore.hideBalanceQuery || isOpenAiUrl;
}, [accessStore.hideBalanceQuery, accessStore.openaiUrl]);
const usage = {
used: updateStore.used,
subscription: updateStore.subscription,
};
const [loadingUsage, setLoadingUsage] = useState(false);
function checkUsage(force = false) {
if (accessStore.hideBalanceQuery) {
if (shouldHideBalanceQuery) {
return;
}
@@ -587,7 +599,6 @@ export function Settings() {
});
}
const accessStore = useAccessStore();
const enabledAccessControl = useMemo(
() => accessStore.enabledAccessControl(),
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -877,7 +888,9 @@ export function Settings() {
type="text"
placeholder={Locale.Settings.AccessCode.Placeholder}
onChange={(e) => {
accessStore.updateCode(e.currentTarget.value);
accessStore.update(
(access) => (access.accessCode = e.currentTarget.value),
);
}}
/>
</ListItem>
@@ -896,7 +909,9 @@ export function Settings() {
value={accessStore.openaiUrl}
placeholder="https://api.openai.com/"
onChange={(e) =>
accessStore.updateOpenAiUrl(e.currentTarget.value)
accessStore.update(
(access) => (access.openaiUrl = e.currentTarget.value),
)
}
></input>
</ListItem>
@@ -909,14 +924,16 @@ export function Settings() {
type="text"
placeholder={Locale.Settings.Token.Placeholder}
onChange={(e) => {
accessStore.updateToken(e.currentTarget.value);
accessStore.update(
(access) => (access.token = e.currentTarget.value),
);
}}
/>
</ListItem>
</>
) : null}
{!accessStore.hideBalanceQuery ? (
{!shouldHideBalanceQuery ? (
<ListItem
title={Locale.Settings.Usage.Title}
subTitle={

View File

@@ -1,4 +1,4 @@
import { useEffect, useRef, useCallback } from "react";
import { useEffect, useRef, useCallback, useMemo } from "react";
import styles from "./home.module.scss";
@@ -26,7 +26,7 @@ import {
} from "../constant";
import { Link, useNavigate } from "react-router-dom";
import { useMobileScreen } from "../utils";
import { isIOS, useMobileScreen } from "../utils";
import dynamic from "next/dynamic";
import { showConfirm, showToast } from "./ui-lib";
@@ -134,6 +134,11 @@ export function SideBar(props: { className?: string }) {
const { onDragStart, shouldNarrow } = useDragSideBar();
const navigate = useNavigate();
const config = useAppConfig();
const isMobileScreen = useMobileScreen();
const isIOSMobile = useMemo(
() => isIOS() && isMobileScreen,
[isMobileScreen],
);
useHotKey();
@@ -142,6 +147,10 @@ export function SideBar(props: { className?: string }) {
className={`${styles.sidebar} ${props.className} ${
shouldNarrow && styles["narrow-sidebar"]
}`}
style={{
// #3016 disable transition on ios mobile screen
transition: isMobileScreen && isIOSMobile ? "none" : undefined,
}}
>
<div className={styles["sidebar-header"]} data-tauri-drag-region>
<div className={styles["sidebar-title"]} data-tauri-drag-region>

View File

@@ -12,7 +12,8 @@ declare global {
DISABLE_GPT4?: string; // allow user to use gpt-4 or not
BUILD_MODE?: "standalone" | "export";
BUILD_APP?: string; // is building desktop app
HIDE_BALANCE_QUERY?: string; // allow user to query balance or not
ENABLE_BALANCE_QUERY?: string; // allow user to query balance or not
DISABLE_FAST_LINK?: string; // disallow parse settings from url or not
}
}
}
@@ -47,6 +48,7 @@ export const getServerSideConfig = () => {
isVercel: !!process.env.VERCEL,
hideUserApiKey: !!process.env.HIDE_USER_API_KEY,
disableGPT4: !!process.env.DISABLE_GPT4,
hideBalanceQuery: !!process.env.HIDE_BALANCE_QUERY,
hideBalanceQuery: !process.env.ENABLE_BALANCE_QUERY,
disableFastLink: !!process.env.DISABLE_FAST_LINK,
};
};

View File

@@ -10,6 +10,7 @@ export const RUNTIME_CONFIG_DOM = "danger-runtime-config";
export const DEFAULT_CORS_HOST = "https://ab.nextweb.fun";
export const DEFAULT_API_HOST = `${DEFAULT_CORS_HOST}/api/proxy`;
export const OPENAI_BASE_URL = "https://api.openai.com";
export enum Path {
Home = "/",
@@ -69,12 +70,20 @@ export const OpenaiPath = {
export const DEFAULT_INPUT_TEMPLATE = `{{input}}`; // input / time / model / lang
export const DEFAULT_SYSTEM_TEMPLATE = `
You are ChatGPT, a large language model trained by OpenAI.
Knowledge cutoff: 2021-09
Knowledge cutoff: {{cutoff}}
Current model: {{model}}
Current time: {{time}}`;
Current time: {{time}}
`;
export const SUMMARIZE_MODEL = "gpt-3.5-turbo";
export const KnowledgeCutOffDate: Record<string, string> = {
default: "2021-09",
"gpt-3.5-turbo-1106": "2023-04",
"gpt-4-1106-preview": "2023-04",
"gpt-4-vision-preview": "2023-04",
};
export const DEFAULT_MODELS = [
{
name: "gpt-4",
@@ -100,6 +109,14 @@ export const DEFAULT_MODELS = [
name: "gpt-4-32k-0613",
available: true,
},
{
name: "gpt-4-1106-preview",
available: true,
},
{
name: "gpt-4-vision-preview",
available: true,
},
{
name: "gpt-3.5-turbo",
available: true,
@@ -112,6 +129,10 @@ export const DEFAULT_MODELS = [
name: "gpt-3.5-turbo-0613",
available: true,
},
{
name: "gpt-3.5-turbo-1106",
available: true,
},
{
name: "gpt-3.5-turbo-16k",
available: true,

View File

@@ -16,6 +16,7 @@ const DEFAULT_ACCESS_STATE = {
hideUserApiKey: false,
hideBalanceQuery: false,
disableGPT4: false,
disableFastLink: false,
openaiUrl: DEFAULT_OPENAI_URL,
};
@@ -29,15 +30,6 @@ export const useAccessStore = createPersistStore(
return get().needCode;
},
updateCode(code: string) {
set(() => ({ accessCode: code?.trim() }));
},
updateToken(token: string) {
set(() => ({ token: token?.trim() }));
},
updateOpenAiUrl(url: string) {
set(() => ({ openaiUrl: url?.trim() }));
},
isAuthorized() {
this.fetch();

View File

@@ -7,6 +7,7 @@ import { createEmptyMask, Mask } from "./mask";
import {
DEFAULT_INPUT_TEMPLATE,
DEFAULT_SYSTEM_TEMPLATE,
KnowledgeCutOffDate,
StoreKey,
SUMMARIZE_MODEL,
} from "../constant";
@@ -116,7 +117,11 @@ function countMessages(msgs: ChatMessage[]) {
}
function fillTemplateWith(input: string, modelConfig: ModelConfig) {
let cutoff =
KnowledgeCutOffDate[modelConfig.model] ?? KnowledgeCutOffDate.default;
const vars = {
cutoff,
model: modelConfig.model,
time: new Date().toLocaleString(),
lang: getLang(),

View File

@@ -133,7 +133,9 @@ export const useAppConfig = createPersistStore(
.customModels.split(",")
.filter((v) => !!v && v.length > 0)
.map((m) => ({ name: m, available: true }));
return get().models.concat(customModels);
const allModels = get().models.concat(customModels);
allModels.sort((a, b) => (a.name < b.name ? -1 : 1));
return allModels;
},
}),
{