refactor(client): update file handling in file upload functions
This commit is contained in:
parent
1f2dea448a
commit
e6ef10e96e
|
@ -37,14 +37,14 @@ export interface MultimodalContent {
|
||||||
file_url?: {
|
file_url?: {
|
||||||
url: string;
|
url: string;
|
||||||
name: string;
|
name: string;
|
||||||
tokenCount?: string;
|
tokenCount?: number;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UploadFile {
|
export interface UploadFile {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
tokenCount?: string;
|
tokenCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RequestMessage {
|
export interface RequestMessage {
|
||||||
|
|
|
@ -71,37 +71,32 @@
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
|
||||||
.attach-file-name-full {
|
%attach-file-name-common {
|
||||||
max-width:calc(62vw);
|
display:flex;
|
||||||
display:flex;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.attach-file-name-full {
|
||||||
|
@extend %attach-file-name-common;
|
||||||
|
max-width:calc(62vw);
|
||||||
|
}
|
||||||
|
|
||||||
.attach-file-name-half {
|
.attach-file-name-half {
|
||||||
|
@extend %attach-file-name-common;
|
||||||
max-width:calc(45vw);
|
max-width:calc(45vw);
|
||||||
display:flex;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.attach-file-name-less {
|
.attach-file-name-less {
|
||||||
|
@extend %attach-file-name-common;
|
||||||
max-width:calc(28vw);
|
max-width:calc(28vw);
|
||||||
display:flex;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.attach-file-name-min {
|
.attach-file-name-min {
|
||||||
|
@extend %attach-file-name-common;
|
||||||
max-width:calc(12vw);
|
max-width:calc(12vw);
|
||||||
display:flex;
|
}
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
.attach-file-icon {
|
.attach-file-icon {
|
||||||
min-width: 16px;
|
min-width: 16px;
|
||||||
max-width: 16px;
|
max-width: 16px;
|
||||||
|
|
|
@ -80,6 +80,7 @@ import {
|
||||||
import type { UploadFile } from "../client/api";
|
import type { UploadFile } from "../client/api";
|
||||||
|
|
||||||
import { uploadImage as uploadImageRemote } from "@/app/utils/chat";
|
import { uploadImage as uploadImageRemote } from "@/app/utils/chat";
|
||||||
|
import { uploadImage as uploadFileRemote } from "@/app/utils/chat";
|
||||||
|
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
|
|
||||||
|
@ -1193,7 +1194,9 @@ function _Chat() {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const textContent = getMessageTextContent(userMessage);
|
const textContent = getMessageTextContent(userMessage);
|
||||||
const images = getMessageImages(userMessage);
|
const images = getMessageImages(userMessage);
|
||||||
chatStore.onUserInput(textContent, images).then(() => setIsLoading(false));
|
chatStore
|
||||||
|
.onUserInput(textContent, images, attachFiles)
|
||||||
|
.then(() => setIsLoading(false));
|
||||||
inputRef.current?.focus();
|
inputRef.current?.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1488,20 +1491,20 @@ function _Chat() {
|
||||||
fileInput.multiple = true;
|
fileInput.multiple = true;
|
||||||
fileInput.onchange = (event: any) => {
|
fileInput.onchange = (event: any) => {
|
||||||
setUploading(true);
|
setUploading(true);
|
||||||
const files = event.target.files;
|
const inputFiles = event.target.files;
|
||||||
const imagesData: UploadFile[] = [];
|
const imagesData: UploadFile[] = [];
|
||||||
(async () => {
|
(async () => {
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < inputFiles.length; i++) {
|
||||||
const file = files[i];
|
const file = inputFiles[i];
|
||||||
try {
|
try {
|
||||||
const dataUrl = await uploadImageRemote(file);
|
const dataUrl = await uploadFileRemote(file);
|
||||||
const fileData: UploadFile = { name: file.name, url: dataUrl };
|
const fileData: UploadFile = { name: file.name, url: dataUrl };
|
||||||
const tokenCount = await countTokens(fileData);
|
const tokenCount: number = await countTokens(fileData);
|
||||||
fileData.tokenCount = tokenCount;
|
fileData.tokenCount = tokenCount;
|
||||||
imagesData.push(fileData);
|
imagesData.push(fileData);
|
||||||
if (
|
if (
|
||||||
imagesData.length === 3 ||
|
imagesData.length === 3 ||
|
||||||
imagesData.length === files.length
|
imagesData.length === inputFiles.length
|
||||||
) {
|
) {
|
||||||
setUploading(false);
|
setUploading(false);
|
||||||
res(imagesData);
|
res(imagesData);
|
||||||
|
@ -1945,7 +1948,7 @@ function _Chat() {
|
||||||
{getMessageFiles(message).length > 0 && (
|
{getMessageFiles(message).length > 0 && (
|
||||||
<div className={styles["chat-message-item-files"]}>
|
<div className={styles["chat-message-item-files"]}>
|
||||||
{getMessageFiles(message).map((file, index) => {
|
{getMessageFiles(message).map((file, index) => {
|
||||||
const extension: DefaultExtensionType = file.url
|
const extension: DefaultExtensionType = file.name
|
||||||
.split(".")
|
.split(".")
|
||||||
.pop()
|
.pop()
|
||||||
?.toLowerCase() as DefaultExtensionType;
|
?.toLowerCase() as DefaultExtensionType;
|
||||||
|
@ -1970,7 +1973,7 @@ function _Chat() {
|
||||||
styles["chat-message-item-file-name"]
|
styles["chat-message-item-file-name"]
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{file.name} {file.tokenCount}
|
{file.name} {file.tokenCount}K
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
@ -2072,7 +2075,7 @@ function _Chat() {
|
||||||
{attachFiles.length != 0 && (
|
{attachFiles.length != 0 && (
|
||||||
<div className={styles["attach-files"]}>
|
<div className={styles["attach-files"]}>
|
||||||
{attachFiles.map((file, index) => {
|
{attachFiles.map((file, index) => {
|
||||||
const extension: DefaultExtensionType = file.url
|
const extension: DefaultExtensionType = file.name
|
||||||
.split(".")
|
.split(".")
|
||||||
.pop()
|
.pop()
|
||||||
?.toLowerCase() as DefaultExtensionType;
|
?.toLowerCase() as DefaultExtensionType;
|
||||||
|
@ -2087,22 +2090,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.tokenCount}
|
{file.name} {file.tokenCount}K
|
||||||
</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.tokenCount}
|
{file.name} {file.tokenCount}K
|
||||||
</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.tokenCount}
|
{file.name} {file.tokenCount}K
|
||||||
</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.tokenCount}
|
{file.name} {file.tokenCount}K
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -351,6 +351,7 @@ export const useChatStore = createPersistStore(
|
||||||
if (attachFiles && attachFiles.length > 0) {
|
if (attachFiles && attachFiles.length > 0) {
|
||||||
let fileContent = userContent + " Here are the files: \n";
|
let fileContent = userContent + " Here are the files: \n";
|
||||||
for (let i = 0; i < attachFiles.length; i++) {
|
for (let i = 0; i < attachFiles.length; i++) {
|
||||||
|
fileContent += attachFiles[i].name + "\n";
|
||||||
fileContent += await readFileContent(attachFiles[i]);
|
fileContent += await readFileContent(attachFiles[i]);
|
||||||
}
|
}
|
||||||
mContent = [
|
mContent = [
|
||||||
|
|
17
app/utils.ts
17
app/utils.ts
|
@ -18,6 +18,10 @@ export function trimTopic(topic: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const readFileContent = async (file: UploadFile): Promise<string> => {
|
export const readFileContent = async (file: UploadFile): Promise<string> => {
|
||||||
|
const host_url = new URL(window.location.href);
|
||||||
|
if (!file.url.includes(host_url.host)) {
|
||||||
|
throw new Error(`The URL ${file.url} is not allowed to access.`);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const response = await fetch(file.url);
|
const response = await fetch(file.url);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
@ -25,9 +29,10 @@ export const readFileContent = async (file: UploadFile): Promise<string> => {
|
||||||
`Failed to fetch content from ${file.url}: ${response.statusText}`,
|
`Failed to fetch content from ${file.url}: ${response.statusText}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const content = await response.text();
|
//const content = await response.text();
|
||||||
const result = file.name + "\n" + content;
|
//const result = file.name + "\n" + content;
|
||||||
return result;
|
//return result;
|
||||||
|
return await response.text();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error reading file content:", error);
|
console.error("Error reading file content:", error);
|
||||||
return "";
|
return "";
|
||||||
|
@ -60,7 +65,7 @@ export const countTokens = async (file: UploadFile) => {
|
||||||
totalTokens += 0.98;
|
totalTokens += 0.98;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let totalTokenCount = (totalTokens / 1000).toFixed(2).toString() + "K";
|
const totalTokenCount: number = +(totalTokens / 1000).toFixed(2);
|
||||||
return totalTokenCount;
|
return totalTokenCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -303,8 +308,8 @@ export function getMessageFiles(message: RequestMessage): UploadFile[] {
|
||||||
}
|
}
|
||||||
const files: UploadFile[] = [];
|
const files: UploadFile[] = [];
|
||||||
for (const c of message.content) {
|
for (const c of message.content) {
|
||||||
if (c.type === "file_url") {
|
if (c.type === "file_url" && c.file_url) {
|
||||||
files.push(c.file_url ? c.file_url : { name: "", url: "" });
|
files.push(c.file_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return files;
|
return files;
|
||||||
|
|
Loading…
Reference in New Issue