Skip to content

Commit

Permalink
Merge pull request #1361 from Yidadaa/bugfix-0509
Browse files Browse the repository at this point in the history
feat: #1055, #444 and fix #1359 hot key to switch chat and allow to disable gpt-4
  • Loading branch information
Yidadaa authored May 9, 2023
2 parents f4caa00 + e4630e6 commit dae7da0
Show file tree
Hide file tree
Showing 13 changed files with 81 additions and 19 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,13 @@ Specify OpenAI organization ID.

> Default: Empty
If you do not want users to input their own API key, set this environment variable to 1.
If you do not want users to input their own API key, set this value to 1.

### `DISABLE_GPT4` (optional)

> Default: Empty
If you do not want users to use GPT-4, set this value to 1.

## Development

Expand Down
6 changes: 5 additions & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ code1,code2,code3

## 环境变量

> 本项目大多数配置项都通过环境变量来设置。
> 本项目大多数配置项都通过环境变量来设置,教程:[如何修改 Vercel 环境变量](./docs/vercel-cn.md)
### `OPENAI_API_KEY` (必填项)

Expand Down Expand Up @@ -94,6 +94,10 @@ OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填

如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。

### `DISABLE_GPT4` (可选)

如果你不想让用户使用 GPT-4,将此环境变量设置为 1 即可。

## 开发

> 强烈不建议在本地进行开发或者部署,由于一些技术原因,很难在本地配置好 OpenAI API 代理,除非你能保证可以直连 OpenAI 服务器。
Expand Down
3 changes: 2 additions & 1 deletion app/api/config/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NextRequest, NextResponse } from "next/server";
import { NextResponse } from "next/server";

import { getServerSideConfig } from "../../config/server";

Expand All @@ -9,6 +9,7 @@ const serverConfig = getServerSideConfig();
const DANGER_CONFIG = {
needCode: serverConfig.needCode,
hideUserApiKey: serverConfig.hideUserApiKey,
enableGPT4: serverConfig.enableGPT4,
};

declare global {
Expand Down
14 changes: 4 additions & 10 deletions app/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import chatStyle from "./chat.module.scss";

import { ListItem, Modal, showModal } from "./ui-lib";
import { useLocation, useNavigate } from "react-router-dom";
import { Path } from "../constant";
import { LAST_INPUT_KEY, Path } from "../constant";
import { Avatar } from "./emoji";
import { MaskAvatar, MaskConfig } from "./mask";
import { useMaskStore } from "../store/mask";
Expand Down Expand Up @@ -404,7 +404,6 @@ export function Chat() {

const inputRef = useRef<HTMLTextAreaElement>(null);
const [userInput, setUserInput] = useState("");
const [beforeInput, setBeforeInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const { submitKey, shouldSubmit } = useSubmitHandler();
const { scrollRef, setAutoScroll, scrollToBottom } = useScrollToBottom();
Expand Down Expand Up @@ -477,7 +476,7 @@ export function Chat() {
if (userInput.trim() === "") return;
setIsLoading(true);
chatStore.onUserInput(userInput).then(() => setIsLoading(false));
setBeforeInput(userInput);
localStorage.setItem(LAST_INPUT_KEY, userInput);
setUserInput("");
setPromptHints([]);
if (!isMobileScreen) inputRef.current?.focus();
Expand All @@ -491,9 +490,9 @@ export function Chat() {

// check if should send message
const onInputKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
// if ArrowUp and no userInput
// if ArrowUp and no userInput, fill with last input
if (e.key === "ArrowUp" && userInput.length <= 0) {
setUserInput(beforeInput);
setUserInput(localStorage.getItem(LAST_INPUT_KEY) ?? "");
e.preventDefault();
return;
}
Expand All @@ -503,11 +502,6 @@ export function Chat() {
}
};
const onRightClick = (e: any, message: Message) => {
// auto fill user input
if (message.role === "user") {
setUserInput(message.content);
}

// copy to clipboard
if (selectOrCopy(e.currentTarget, message.content)) {
e.preventDefault();
Expand Down
2 changes: 1 addition & 1 deletion app/components/mask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import CopyIcon from "../icons/copy.svg";

import { DEFAULT_MASK_AVATAR, Mask, useMaskStore } from "../store/mask";
import { Message, ModelConfig, ROLES, useChatStore } from "../store";
import { Input, List, ListItem, Modal, Popover, showToast } from "./ui-lib";
import { Input, List, ListItem, Modal, Popover } from "./ui-lib";
import { Avatar, AvatarPicker } from "./emoji";
import Locale, { AllLangs, Lang } from "../locales";
import { useNavigate } from "react-router-dom";
Expand Down
25 changes: 24 additions & 1 deletion app/components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@ const ChatList = dynamic(async () => (await import("./chat-list")).ChatList, {
loading: () => null,
});

function useHotKey() {
const chatStore = useChatStore();

useEffect(() => {
const onKeyDown = (e: KeyboardEvent) => {
if (e.metaKey || e.altKey || e.ctrlKey) {
const n = chatStore.sessions.length;
const limit = (x: number) => (x + n) % n;
const i = chatStore.currentSessionIndex;
if (e.key === "ArrowUp") {
chatStore.selectSession(limit(i - 1));
} else if (e.key === "ArrowDown") {
chatStore.selectSession(limit(i + 1));
}
}
};

window.addEventListener("keydown", onKeyDown);
return () => window.removeEventListener("keydown", onKeyDown);
});
}

function useDragSideBar() {
const limit = (x: number) => Math.min(MAX_SIDEBAR_WIDTH, x);

Expand Down Expand Up @@ -86,9 +108,10 @@ export function SideBar(props: { className?: string }) {
// drag side bar
const { onDragMouseDown, shouldNarrow } = useDragSideBar();
const navigate = useNavigate();

const config = useAppConfig();

useHotKey();

return (
<div
className={`${styles.sidebar} ${props.className} ${
Expand Down
2 changes: 2 additions & 0 deletions app/config/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ declare global {
PROXY_URL?: string;
VERCEL?: string;
HIDE_USER_API_KEY?: string; // disable user's api key input
DISABLE_GPT4?: string; // allow user to use gpt-4 or not
}
}
}
Expand Down Expand Up @@ -40,5 +41,6 @@ export const getServerSideConfig = () => {
proxyUrl: process.env.PROXY_URL,
isVercel: !!process.env.VERCEL,
hideUserApiKey: !!process.env.HIDE_USER_API_KEY,
enableGPT4: !process.env.DISABLE_GPT4,
};
};
2 changes: 2 additions & 0 deletions app/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ export const MIN_SIDEBAR_WIDTH = 230;
export const NARROW_SIDEBAR_WIDTH = 100;

export const ACCESS_CODE_PREFIX = "ak-";

export const LAST_INPUT_KEY = "last-input";
2 changes: 1 addition & 1 deletion app/masks/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const EN_MASKS: BuiltinMask[] = [
],
modelConfig: {
model: "gpt-4",
temperature: 1,
temperature: 0.5,
max_tokens: 2000,
presence_penalty: 0,
sendMemory: true,
Expand Down
9 changes: 9 additions & 0 deletions app/store/access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { create } from "zustand";
import { persist } from "zustand/middleware";
import { StoreKey } from "../constant";
import { BOT_HELLO } from "./chat";
import { ALL_MODELS } from "./config";

export interface AccessControlStore {
accessCode: string;
Expand Down Expand Up @@ -60,6 +61,14 @@ export const useAccessStore = create<AccessControlStore>()(
console.log("[Config] got config from server", res);
set(() => ({ ...res }));

if (!res.enableGPT4) {
ALL_MODELS.forEach((model) => {
if (model.name.startsWith("gpt-4")) {
(model as any).available = false;
}
});
}

if ((res as any).botHello) {
BOT_HELLO.content = (res as any).botHello;
}
Expand Down
3 changes: 2 additions & 1 deletion app/store/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,9 @@ export const useChatStore = create<ChatStore>()(
const sessions = get().sessions.slice();
sessions.splice(index, 1);

const currentIndex = get().currentSessionIndex;
let nextIndex = Math.min(
get().currentSessionIndex,
currentIndex - Number(index < currentIndex),
sessions.length - 1,
);

Expand Down
20 changes: 20 additions & 0 deletions app/store/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@ export const ALL_MODELS = [
name: "gpt-3.5-turbo-0301",
available: true,
},
{
name: "qwen-v1", // 通义千问
available: false,
},
{
name: "ernie", // 文心一言
available: false,
},
{
name: "spark", // 讯飞星火
available: false,
},
{
name: "llama", // llama
available: false,
},
{
name: "chatglm", // chatglm-6b
available: false,
},
] as const;

export type ModelType = (typeof ALL_MODELS)[number]["name"];
Expand Down
4 changes: 2 additions & 2 deletions app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,13 @@ export function autoGrowTextArea(dom: HTMLTextAreaElement) {
measureDom.style.width = width + "px";
measureDom.innerText = dom.value.trim().length > 0 ? dom.value : "1";

const lineWrapCount = Math.max(0, dom.value.split("\n").length - 1);
const emptyLineWrap = Math.max(0, dom.value.split("\n\n").length - 1);
const height = parseFloat(window.getComputedStyle(measureDom).height);
const singleLineHeight = parseFloat(
window.getComputedStyle(singleLineDom).height,
);

const rows = Math.round(height / singleLineHeight) + lineWrapCount;
const rows = Math.round(height / singleLineHeight) + emptyLineWrap;

return rows;
}
Expand Down

0 comments on commit dae7da0

Please sign in to comment.