mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-03 00:26:40 +08:00
commit
4e2446a963
@ -4,15 +4,16 @@ import { insertUser } from "@/lib/auth";
|
||||
// import { getTokenLength } from "@/app/utils/token";
|
||||
// import { Tiktoken } from "tiktoken/lite"
|
||||
// import cl100k_base from "tiktoken/encoders/cl100k_base.json"
|
||||
import "tiktoken";
|
||||
import { get_encoding } from "tiktoken";
|
||||
// import "tiktoken";
|
||||
// import { get_encoding } from "tiktoken";
|
||||
import { addHours, subMinutes } from "date-fns";
|
||||
import { getTokenLength } from "@/lib/utils";
|
||||
|
||||
function getTokenLength(input: string): number {
|
||||
const encoding = get_encoding("cl100k_base");
|
||||
// console.log('tokens: ', input, encoding.countTokens())
|
||||
return encoding.encode(input).length;
|
||||
}
|
||||
// function getTokenLength(input: string): number {
|
||||
// const encoding = get_encoding("cl100k_base");
|
||||
// // console.log('tokens: ', input, encoding.countTokens())
|
||||
// return encoding.encode(input).length;
|
||||
// }
|
||||
|
||||
async function handle(
|
||||
req: NextRequest,
|
||||
|
@ -50,6 +50,7 @@ import {
|
||||
useAppConfig,
|
||||
DEFAULT_TOPIC,
|
||||
ModelType,
|
||||
ChatSession,
|
||||
} from "../store";
|
||||
|
||||
import {
|
||||
@ -101,6 +102,7 @@ import { Button } from "emoji-picker-react/src/components/atoms/Button";
|
||||
import Image from "next/image";
|
||||
import { useAllModels } from "../utils/hooks";
|
||||
import { MultimodalContent } from "../client/api";
|
||||
import { getTokenLength } from "@/lib/utils";
|
||||
|
||||
const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
|
||||
loading: () => <LoadingIcon />,
|
||||
@ -350,9 +352,10 @@ function ChatAction(props: {
|
||||
icon: 16,
|
||||
});
|
||||
const allModels = useAllModels().map((item) => item.displayName);
|
||||
const customModelClassName = allModels.includes(props.text)
|
||||
? "chat-input-action-long-weight"
|
||||
: "";
|
||||
let customModelClassName = "";
|
||||
if (props.text.includes("使用") || allModels.includes(props.text)) {
|
||||
customModelClassName = "chat-input-action-long-weight";
|
||||
}
|
||||
|
||||
function updateWidth() {
|
||||
if (!iconRef.current || !textRef.current) return;
|
||||
@ -466,6 +469,7 @@ export function ChatActions(props: {
|
||||
);
|
||||
const [showModelSelector, setShowModelSelector] = useState(false);
|
||||
const [showUploadImage, setShowUploadImage] = useState(false);
|
||||
const current_day_token = localStorage.getItem("current_day_token") ?? "";
|
||||
|
||||
useEffect(() => {
|
||||
const show = isVisionModel(currentModel);
|
||||
@ -602,6 +606,22 @@ export function ChatActions(props: {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/*<ChatAction*/}
|
||||
{/* onClick={() => false}*/}
|
||||
{/* text={"使用 " + current_day_token}*/}
|
||||
{/* icon={*/}
|
||||
{/* <img*/}
|
||||
{/* alt="😀"*/}
|
||||
{/* loading="lazy"*/}
|
||||
{/* width="20"*/}
|
||||
{/* height="20"*/}
|
||||
{/* decoding="async"*/}
|
||||
{/* srcSet="/grinning-face.webp"*/}
|
||||
{/* style={{ color: "transparent" }}*/}
|
||||
{/* />*/}
|
||||
{/* }*/}
|
||||
{/*/>*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1141,6 +1161,49 @@ function _Chat() {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const handlePaste = useCallback(
|
||||
async (event: React.ClipboardEvent<HTMLTextAreaElement>) => {
|
||||
const currentModel = chatStore.currentSession().mask.modelConfig.model;
|
||||
if (!isVisionModel(currentModel)) {
|
||||
return;
|
||||
}
|
||||
const items = (event.clipboardData || window.clipboardData).items;
|
||||
for (const item of items) {
|
||||
if (item.kind === "file" && item.type.startsWith("image/")) {
|
||||
event.preventDefault();
|
||||
const file = item.getAsFile();
|
||||
if (file) {
|
||||
const images: string[] = [];
|
||||
images.push(...attachImages);
|
||||
images.push(
|
||||
...(await new Promise<string[]>((res, rej) => {
|
||||
setUploading(true);
|
||||
const imagesData: string[] = [];
|
||||
compressImage(file, 256 * 1024)
|
||||
.then((dataUrl) => {
|
||||
imagesData.push(dataUrl);
|
||||
setUploading(false);
|
||||
res(imagesData);
|
||||
})
|
||||
.catch((e) => {
|
||||
setUploading(false);
|
||||
rej(e);
|
||||
});
|
||||
})),
|
||||
);
|
||||
const imagesLength = images.length;
|
||||
|
||||
if (imagesLength > 3) {
|
||||
images.splice(3, imagesLength - 3);
|
||||
}
|
||||
setAttachImages(images);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
[attachImages, chatStore],
|
||||
);
|
||||
|
||||
async function uploadImage() {
|
||||
const images: string[] = [];
|
||||
images.push(...attachImages);
|
||||
@ -1211,6 +1274,10 @@ function _Chat() {
|
||||
</div>
|
||||
<div className="window-header-sub-title">
|
||||
{Locale.Chat.SubTitle(session.messages.length)}
|
||||
<span>
|
||||
当天使用:
|
||||
{localStorage.getItem("current_day_token") ?? 0}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="window-actions">
|
||||
@ -1589,6 +1656,7 @@ function _Chat() {
|
||||
onKeyDown={onInputKeyDown}
|
||||
onFocus={scrollToBottom}
|
||||
onClick={scrollToBottom}
|
||||
onPaste={handlePaste}
|
||||
rows={inputRows}
|
||||
autoFocus={autoFocus}
|
||||
style={{
|
||||
@ -1643,8 +1711,45 @@ function _Chat() {
|
||||
);
|
||||
}
|
||||
|
||||
function getCurrentDayToken(sessions: ChatSession[]): number {
|
||||
try {
|
||||
const currentTime = new Date();
|
||||
const startOfTheDayInTimeZone = new Date(
|
||||
currentTime.getFullYear(),
|
||||
currentTime.getMonth(),
|
||||
currentTime.getDate(),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
const current_day_message = sessions
|
||||
.reduce((acc, item) => {
|
||||
// @ts-ignore
|
||||
return acc.concat(item.messages);
|
||||
}, [])
|
||||
.filter((item1) => {
|
||||
// @ts-ignore
|
||||
const dateToCheck = new Date(item1.date);
|
||||
return startOfTheDayInTimeZone < dateToCheck;
|
||||
});
|
||||
const all_current_day_content = current_day_message
|
||||
// @ts-ignore
|
||||
.map((item) => item.content)
|
||||
.join(" ");
|
||||
// 获取会话之后,再整合content,
|
||||
return getTokenLength(all_current_day_content);
|
||||
} catch (e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
export function Chat() {
|
||||
const chatStore = useChatStore();
|
||||
const sessionIndex = chatStore.currentSessionIndex;
|
||||
// 这里计先计算一下当天总token数。
|
||||
localStorage.setItem(
|
||||
"current_day_token",
|
||||
String(getCurrentDayToken(chatStore.sessions)),
|
||||
);
|
||||
return <_Chat key={sessionIndex}></_Chat>;
|
||||
}
|
||||
|
@ -23,19 +23,19 @@ export function estimateTokenLength(input: string): number {
|
||||
|
||||
// import { get_encoding } from "tiktoken";
|
||||
|
||||
export function getTokenLength(input: string): number {
|
||||
// const { get_encoding } = require( "tiktoken" );
|
||||
// const encoding = get_encoding("cl100k_base");
|
||||
|
||||
const { Tiktoken } = require("tiktoken/lite");
|
||||
const cl100k_base = require("tiktoken/encoders/cl100k_base.json");
|
||||
const encoding = new Tiktoken(
|
||||
cl100k_base.bpe_ranks,
|
||||
cl100k_base.special_tokens,
|
||||
cl100k_base.pat_str,
|
||||
);
|
||||
const tokenLength = encoding.encode(input).length;
|
||||
// console.log('[TOKEN],=========', input, tokenLength)
|
||||
|
||||
return tokenLength;
|
||||
}
|
||||
// export function getTokenLength(input: string): number {
|
||||
// // const { get_encoding } = require( "tiktoken" );
|
||||
// // const encoding = get_encoding("cl100k_base");
|
||||
//
|
||||
// const { Tiktoken } = require("tiktoken/lite");
|
||||
// const cl100k_base = require("tiktoken/encoders/cl100k_base.json");
|
||||
// const encoding = new Tiktoken(
|
||||
// cl100k_base.bpe_ranks,
|
||||
// cl100k_base.special_tokens,
|
||||
// cl100k_base.pat_str,
|
||||
// );
|
||||
// const tokenLength = encoding.encode(input).length;
|
||||
// // console.log('[TOKEN],=========', input, tokenLength)
|
||||
//
|
||||
// return tokenLength;
|
||||
// }
|
||||
|
@ -4,7 +4,8 @@ export const DENY_LIST: string[] = [
|
||||
]
|
||||
export const ADMIN_LIST: string[] = [
|
||||
"司金辉", "sijinhui", "sijinhui@qq.com",
|
||||
"yuchuan", "于川"
|
||||
"yuchuan", "于川",
|
||||
"jujujujuju",
|
||||
]
|
||||
|
||||
|
||||
|
14
lib/utils.ts
14
lib/utils.ts
@ -1,9 +1,13 @@
|
||||
// import { clsx, type ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
// export function cn(...inputs: ClassValue[]) {
|
||||
// return twMerge(clsx(inputs));
|
||||
// }
|
||||
import {get_encoding} from "tiktoken";
|
||||
|
||||
|
||||
export function getTokenLength(input: string): number {
|
||||
const encoding = get_encoding("cl100k_base");
|
||||
// console.log('tokens: ', input, encoding.countTokens())
|
||||
return encoding.encode(input).length;
|
||||
}
|
||||
|
||||
export async function fetcher<JSON = any>(
|
||||
input: RequestInfo,
|
||||
init?: RequestInit,
|
||||
|
BIN
public/grinning-face.webp
Normal file
BIN
public/grinning-face.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
Loading…
Reference in New Issue
Block a user