refactor: refactor token counting logic in countTokens function
This commit is contained in:
parent
4acc742456
commit
586c4a493d
|
@ -43,6 +43,7 @@ export interface MultimodalContent {
|
||||||
export interface UploadFile {
|
export interface UploadFile {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
tokenCount?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RequestMessage {
|
export interface RequestMessage {
|
||||||
|
|
|
@ -74,6 +74,7 @@ import {
|
||||||
isDalle3,
|
isDalle3,
|
||||||
showPlugins,
|
showPlugins,
|
||||||
safeLocalStorage,
|
safeLocalStorage,
|
||||||
|
countTokens,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
import type { UploadFile } from "../client/api";
|
import type { UploadFile } from "../client/api";
|
||||||
|
@ -1489,11 +1490,15 @@ function _Chat() {
|
||||||
setUploading(true);
|
setUploading(true);
|
||||||
const files = event.target.files;
|
const files = event.target.files;
|
||||||
const imagesData: UploadFile[] = [];
|
const imagesData: UploadFile[] = [];
|
||||||
for (let i = 0; i < files.length; i++) {
|
(async () => {
|
||||||
const file = event.target.files[i];
|
for (let i = 0; i < files.length; i++) {
|
||||||
uploadImageRemote(file)
|
const file = files[i];
|
||||||
.then((dataUrl) => {
|
try {
|
||||||
imagesData.push({ name: file.name, url: dataUrl });
|
const dataUrl = await uploadImageRemote(file);
|
||||||
|
const fileData: UploadFile = { name: file.name, url: dataUrl };
|
||||||
|
const tokenCount = await countTokens(fileData);
|
||||||
|
fileData.tokenCount = tokenCount;
|
||||||
|
imagesData.push(fileData);
|
||||||
if (
|
if (
|
||||||
imagesData.length === 3 ||
|
imagesData.length === 3 ||
|
||||||
imagesData.length === files.length
|
imagesData.length === files.length
|
||||||
|
@ -1501,12 +1506,12 @@ function _Chat() {
|
||||||
setUploading(false);
|
setUploading(false);
|
||||||
res(imagesData);
|
res(imagesData);
|
||||||
}
|
}
|
||||||
})
|
} catch (e) {
|
||||||
.catch((e) => {
|
|
||||||
setUploading(false);
|
setUploading(false);
|
||||||
rej(e);
|
rej(e);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
})();
|
||||||
};
|
};
|
||||||
fileInput.click();
|
fileInput.click();
|
||||||
})),
|
})),
|
||||||
|
@ -1945,7 +1950,6 @@ function _Chat() {
|
||||||
.pop()
|
.pop()
|
||||||
?.toLowerCase() as DefaultExtensionType;
|
?.toLowerCase() as DefaultExtensionType;
|
||||||
const style = defaultStyles[extension];
|
const style = defaultStyles[extension];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
href={file.url}
|
href={file.url}
|
||||||
|
@ -1965,7 +1969,7 @@ function _Chat() {
|
||||||
styles["chat-message-item-file-name"]
|
styles["chat-message-item-file-name"]
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{file.name}
|
{file.name} {file.tokenCount}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
@ -2082,22 +2086,22 @@ function _Chat() {
|
||||||
</div>
|
</div>
|
||||||
{attachImages.length == 0 && (
|
{attachImages.length == 0 && (
|
||||||
<div className={styles["attach-file-name-full"]}>
|
<div className={styles["attach-file-name-full"]}>
|
||||||
{file.name}
|
{file.name} {file.tokenCount}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{attachImages.length == 1 && (
|
{attachImages.length == 1 && (
|
||||||
<div className={styles["attach-file-name-half"]}>
|
<div className={styles["attach-file-name-half"]}>
|
||||||
{file.name}
|
{file.name} {file.tokenCount}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{attachImages.length == 2 && (
|
{attachImages.length == 2 && (
|
||||||
<div className={styles["attach-file-name-less"]}>
|
<div className={styles["attach-file-name-less"]}>
|
||||||
{file.name}
|
{file.name} {file.tokenCount}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{attachImages.length == 3 && (
|
{attachImages.length == 3 && (
|
||||||
<div className={styles["attach-file-name-min"]}>
|
<div className={styles["attach-file-name-min"]}>
|
||||||
{file.name}
|
{file.name} {file.tokenCount}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import {
|
||||||
StoreKey,
|
StoreKey,
|
||||||
} from "../constant";
|
} from "../constant";
|
||||||
import Locale, { getLang } from "../locales";
|
import Locale, { getLang } from "../locales";
|
||||||
import { isDalle3, safeLocalStorage } from "../utils";
|
import { isDalle3, safeLocalStorage, readFileContent } from "../utils";
|
||||||
import { prettyObject } from "../utils/format";
|
import { prettyObject } from "../utils/format";
|
||||||
import { createPersistStore } from "../utils/store";
|
import { createPersistStore } from "../utils/store";
|
||||||
import { estimateTokenLength } from "../utils/token";
|
import { estimateTokenLength } from "../utils/token";
|
||||||
|
@ -154,23 +154,6 @@ function fillTemplateWith(input: string, modelConfig: ModelConfig) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
const readFileContent = async (file: UploadFile): Promise<string> => {
|
|
||||||
try {
|
|
||||||
const response = await fetch(file.url);
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(
|
|
||||||
`Failed to fetch content from ${file.url}: ${response.statusText}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const content = await response.text();
|
|
||||||
const result = file.name + "\n" + content;
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error reading file content:", error);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const DEFAULT_CHAT_STATE = {
|
const DEFAULT_CHAT_STATE = {
|
||||||
sessions: [createEmptySession()],
|
sessions: [createEmptySession()],
|
||||||
currentSessionIndex: 0,
|
currentSessionIndex: 0,
|
||||||
|
|
48
app/utils.ts
48
app/utils.ts
|
@ -17,6 +17,54 @@ export function trimTopic(topic: string) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const readFileContent = async (file: UploadFile): Promise<string> => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(file.url);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
`Failed to fetch content from ${file.url}: ${response.statusText}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const content = await response.text();
|
||||||
|
const result = file.name + "\n" + content;
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error reading file content:", error);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const countTokens = async (file: UploadFile) => {
|
||||||
|
const text = await readFileContent(file);
|
||||||
|
let totalTokens = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < text.length; i++) {
|
||||||
|
const char = text[i];
|
||||||
|
const nextChar = text[i + 1];
|
||||||
|
|
||||||
|
if (char === " " && nextChar === " ") {
|
||||||
|
totalTokens += 0.081;
|
||||||
|
} else if ("NORabcdefghilnopqrstuvy ".includes(char)) {
|
||||||
|
totalTokens += 0.202;
|
||||||
|
} else if ("CHLMPQSTUVfkmspwx".includes(char)) {
|
||||||
|
totalTokens += 0.237;
|
||||||
|
} else if ("-.ABDEFGIKWY_\\r\\tz{ü".includes(char)) {
|
||||||
|
totalTokens += 0.304;
|
||||||
|
} else if ("!{{input}}(/;=JX`j\\n}ö".includes(char)) {
|
||||||
|
totalTokens += 0.416;
|
||||||
|
} else if ('"#%)*+56789<>?@Z[\\]^|§«äç’'.includes(char)) {
|
||||||
|
totalTokens += 0.479;
|
||||||
|
} else if (",01234:~Üß".includes(char) || char.charCodeAt(0) > 255) {
|
||||||
|
totalTokens += 0.658;
|
||||||
|
} else {
|
||||||
|
totalTokens += 0.98;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let totalTokenCount = (totalTokens / 1000).toFixed(2).toString() + "K";
|
||||||
|
console.log(totalTokenCount);
|
||||||
|
return totalTokenCount;
|
||||||
|
};
|
||||||
|
|
||||||
export async function copyToClipboard(text: string) {
|
export async function copyToClipboard(text: string) {
|
||||||
try {
|
try {
|
||||||
if (window.__TAURI__) {
|
if (window.__TAURI__) {
|
||||||
|
|
Loading…
Reference in New Issue