clean up csv prompt + frontend (#3393)

* clean up csv prompt + frontend

* nit

* nit

* detect uploading

* upload
This commit is contained in:
pablonyx 2024-12-11 11:10:34 -08:00 committed by GitHub
parent e255ff7d23
commit e7a7e78969
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 36 additions and 47 deletions

View File

@ -1,5 +1,4 @@
import copy
import io
import json
from collections.abc import Callable
from collections.abc import Iterator
@ -7,7 +6,6 @@ from typing import Any
from typing import cast
import litellm # type: ignore
import pandas as pd
import tiktoken
from langchain.prompts.base import StringPromptValue
from langchain.prompts.chat import ChatPromptValue
@ -100,53 +98,32 @@ def litellm_exception_to_error_msg(
return error_msg
# Processes CSV files to show the first 5 rows and max_columns (default 40) columns
def _process_csv_file(file: InMemoryChatFile, max_columns: int = 40) -> str:
df = pd.read_csv(io.StringIO(file.content.decode("utf-8")))
csv_preview = df.head().to_string(max_cols=max_columns)
file_name_section = (
f"CSV FILE NAME: {file.filename}\n"
if file.filename
else "CSV FILE (NO NAME PROVIDED):\n"
)
return f"{file_name_section}{CODE_BLOCK_PAT.format(csv_preview)}\n\n\n"
def _build_content(
message: str,
files: list[InMemoryChatFile] | None = None,
) -> str:
"""Applies all non-image files."""
text_files = (
[file for file in files if file.file_type == ChatFileType.PLAIN_TEXT]
if files
else None
)
if not files:
return message
csv_files = (
[file for file in files if file.file_type == ChatFileType.CSV]
if files
else None
)
text_files = [
file
for file in files
if file.file_type in (ChatFileType.PLAIN_TEXT, ChatFileType.CSV)
]
if not text_files and not csv_files:
if not text_files:
return message
final_message_with_files = "FILES:\n\n"
for file in text_files or []:
for file in text_files:
file_content = file.content.decode("utf-8")
file_name_section = f"DOCUMENT: {file.filename}\n" if file.filename else ""
final_message_with_files += (
f"{file_name_section}{CODE_BLOCK_PAT.format(file_content.strip())}\n\n\n"
)
for file in csv_files or []:
final_message_with_files += _process_csv_file(file)
final_message_with_files += message
return final_message_with_files
return final_message_with_files + message
def build_content_with_imgs(

View File

@ -1080,10 +1080,17 @@ export function ChatPage({
updateCanContinue(false, frozenSessionId);
if (currentChatState() != "input") {
setPopup({
message: "Please wait for the response to complete",
type: "error",
});
if (currentChatState() == "uploading") {
setPopup({
message: "Please wait for the content to upload",
type: "error",
});
} else {
setPopup({
message: "Please wait for the response to complete",
type: "error",
});
}
return;
}
@ -1558,7 +1565,7 @@ export function ChatPage({
}
};
const handleImageUpload = (acceptedFiles: File[]) => {
const handleImageUpload = async (acceptedFiles: File[]) => {
const [_, llmModel] = getFinalLLM(
llmProviders,
liveAssistant,
@ -1598,8 +1605,9 @@ export function ChatPage({
(file) => !tempFileDescriptors.some((newFile) => newFile.id === file.id)
);
};
updateChatState("uploading", currentSessionId());
uploadFilesForChat(acceptedFiles).then(([files, error]) => {
await uploadFilesForChat(acceptedFiles).then(([files, error]) => {
if (error) {
setCurrentMessageFiles((prev) => removeTempFiles(prev));
setPopup({
@ -1610,6 +1618,7 @@ export function ChatPage({
setCurrentMessageFiles((prev) => [...removeTempFiles(prev), ...files]);
}
});
updateChatState("input", currentSessionId());
};
const [showHistorySidebar, setShowHistorySidebar] = useState(false); // State to track if sidebar is open

View File

@ -1,5 +1,10 @@
export type FeedbackType = "like" | "dislike";
export type ChatState = "input" | "loading" | "streaming" | "toolBuilding";
export type ChatState =
| "input"
| "loading"
| "streaming"
| "toolBuilding"
| "uploading";
export interface RegenerationState {
regenerating: boolean;
finalMessageIndex: number;

View File

@ -91,9 +91,7 @@ const CsvContent: React.FC<ContentComponentProps> = ({
}`}
>
<div
className={`overflow-y-hidden flex relative ${
expanded ? "max-h-2/3" : "max-h-[300px]"
}`}
className={`flex relative ${expanded ? "max-h-2/3" : "max-h-[300px]"}`}
>
<Table>
<TableHeader className="sticky z-[1000] top-0">
@ -108,7 +106,7 @@ const CsvContent: React.FC<ContentComponentProps> = ({
</TableRow>
</TableHeader>
<TableBody className="h-[300px] overflow-y-scroll">
<TableBody className="h-[300px] overflow-y-hidden ">
{data.length > 0 ? (
data.map((row, rowIndex) => (
<TableRow key={rowIndex}>

View File

@ -102,9 +102,9 @@ const ExpandableContentWrapper: React.FC<ExpandableContentWrapperProps> = ({
</div>
</CardHeader>
<Card
className={`!rounded-none w-full ${
expanded ? "max-h-[600px]" : "max-h-[300px] h"
} p-0 relative overflow-x-scroll overflow-y-scroll mx-auto`}
className={`!rounded-none p-0 relative mx-auto w-full ${
expanded ? "max-h-[600px]" : "max-h-[300px] h-full"
} `}
>
<CardContent className="p-0">
<ContentComponent