fix: added empty message on file upload handling, fixed time calculation on onboarding (#316)
* fixed miscalculation of provider steps * Handled empty message with file * fixed same key
This commit is contained in:
parent
31681bb0d9
commit
a7af519d01
6 changed files with 90 additions and 53 deletions
|
|
@ -594,8 +594,8 @@ export function Navigation({
|
|||
No documents yet
|
||||
</div>
|
||||
) : (
|
||||
newConversationFiles?.map((file) => (
|
||||
<div key={`${file}`} className="flex-1 min-w-0 px-3">
|
||||
newConversationFiles?.map((file, index) => (
|
||||
<div key={`${file}-${index}`} className="flex-1 min-w-0 px-3">
|
||||
<div className="text-mmd font-medium text-foreground truncate">
|
||||
{file}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { cn } from "@/lib/utils";
|
|||
import { Message } from "./message";
|
||||
|
||||
interface UserMessageProps {
|
||||
content: string;
|
||||
content: string | undefined;
|
||||
isCompleted?: boolean;
|
||||
animate?: boolean;
|
||||
files?: string;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { type EndpointType, useChat } from "@/contexts/chat-context";
|
|||
import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context";
|
||||
import { useTask } from "@/contexts/task-context";
|
||||
import { useChatStreaming } from "@/hooks/useChatStreaming";
|
||||
import { FILES_REGEX } from "@/lib/constants";
|
||||
import { FILE_CONFIRMATION, FILES_REGEX } from "@/lib/constants";
|
||||
import { useLoadingStore } from "@/stores/loadingStore";
|
||||
import { useGetNudgesQuery } from "../api/queries/useGetNudgesQuery";
|
||||
import { AssistantMessage } from "./components/assistant-message";
|
||||
|
|
@ -911,9 +911,9 @@ function ChatPage() {
|
|||
}
|
||||
|
||||
// Only send message if there's input text
|
||||
if (input.trim()) {
|
||||
if (input.trim() || uploadedFile) {
|
||||
// Pass the responseId from upload (if any) to handleSendMessage
|
||||
handleSendMessage(input, uploadedResponseId || undefined);
|
||||
handleSendMessage(!input.trim() ? FILE_CONFIRMATION : input, uploadedResponseId || undefined);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1154,6 +1154,8 @@ function ChatPage() {
|
|||
}
|
||||
};
|
||||
|
||||
console.log(messages)
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Debug header - only show in debug mode */}
|
||||
|
|
@ -1236,7 +1238,10 @@ function ChatPage() {
|
|||
? message.source !== "langflow"
|
||||
: false
|
||||
}
|
||||
content={message.content}
|
||||
content={index >= 2
|
||||
&& (messages[index - 2]?.content.match(
|
||||
FILES_REGEX,
|
||||
)?.[0] ?? undefined) && message.content === FILE_CONFIRMATION ? undefined : message.content}
|
||||
files={
|
||||
index >= 2
|
||||
? messages[index - 2]?.content.match(
|
||||
|
|
|
|||
|
|
@ -19,34 +19,30 @@ export function AnimatedProviderSteps({
|
|||
setCurrentStep,
|
||||
steps,
|
||||
storageKey = "provider-steps",
|
||||
processingStartTime,
|
||||
}: {
|
||||
currentStep: number;
|
||||
isCompleted: boolean;
|
||||
setCurrentStep: (step: number) => void;
|
||||
steps: string[];
|
||||
storageKey?: string;
|
||||
processingStartTime?: number | null;
|
||||
}) {
|
||||
const [startTime, setStartTime] = useState<number | null>(null);
|
||||
const [elapsedTime, setElapsedTime] = useState<number>(0);
|
||||
|
||||
// Initialize start time from local storage or set new one
|
||||
// Initialize start time from prop or local storage
|
||||
useEffect(() => {
|
||||
const storedStartTime = localStorage.getItem(`${storageKey}-start`);
|
||||
const storedElapsedTime = localStorage.getItem(`${storageKey}-elapsed`);
|
||||
|
||||
if (isCompleted && storedElapsedTime) {
|
||||
// If completed, use stored elapsed time
|
||||
setElapsedTime(parseFloat(storedElapsedTime));
|
||||
} else if (storedStartTime) {
|
||||
// If in progress, use stored start time
|
||||
setStartTime(parseInt(storedStartTime));
|
||||
} else {
|
||||
// First time, set new start time
|
||||
const now = Date.now();
|
||||
setStartTime(now);
|
||||
localStorage.setItem(`${storageKey}-start`, now.toString());
|
||||
} else if (processingStartTime) {
|
||||
// Use the start time passed from parent (when user clicked Complete)
|
||||
setStartTime(processingStartTime);
|
||||
}
|
||||
}, [storageKey, isCompleted]);
|
||||
}, [storageKey, isCompleted, processingStartTime]);
|
||||
|
||||
// Progress through steps
|
||||
useEffect(() => {
|
||||
|
|
@ -64,7 +60,6 @@ export function AnimatedProviderSteps({
|
|||
const elapsed = Date.now() - startTime;
|
||||
setElapsedTime(elapsed);
|
||||
localStorage.setItem(`${storageKey}-elapsed`, elapsed.toString());
|
||||
localStorage.removeItem(`${storageKey}-start`);
|
||||
}
|
||||
}, [isCompleted, startTime, storageKey]);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,12 +32,11 @@ interface OnboardingCardProps {
|
|||
setLoadingStatus?: (status: string[]) => void;
|
||||
}
|
||||
|
||||
|
||||
const STEP_LIST = [
|
||||
"Setting up your model provider",
|
||||
"Defining schema",
|
||||
"Configuring Langflow",
|
||||
"Ingesting sample data",
|
||||
"Setting up your model provider",
|
||||
"Defining schema",
|
||||
"Configuring Langflow",
|
||||
"Ingesting sample data",
|
||||
];
|
||||
|
||||
const TOTAL_PROVIDER_STEPS = STEP_LIST.length;
|
||||
|
|
@ -106,7 +105,13 @@ const OnboardingCard = ({
|
|||
llm_model: "",
|
||||
});
|
||||
|
||||
const [currentStep, setCurrentStep] = useState<number | null>(isCompleted ? TOTAL_PROVIDER_STEPS : null);
|
||||
const [currentStep, setCurrentStep] = useState<number | null>(
|
||||
isCompleted ? TOTAL_PROVIDER_STEPS : null,
|
||||
);
|
||||
|
||||
const [processingStartTime, setProcessingStartTime] = useState<number | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
// Query tasks to track completion
|
||||
const { data: tasks } = useGetTasksQuery({
|
||||
|
|
@ -131,8 +136,8 @@ const OnboardingCard = ({
|
|||
// If no active tasks and we've started onboarding, complete it
|
||||
if (
|
||||
(!activeTasks || (activeTasks.processed_files ?? 0) > 0) &&
|
||||
tasks.length > 0
|
||||
&& !isCompleted
|
||||
tasks.length > 0 &&
|
||||
!isCompleted
|
||||
) {
|
||||
// Set to final step to show "Done"
|
||||
setCurrentStep(TOTAL_PROVIDER_STEPS);
|
||||
|
|
@ -189,6 +194,8 @@ const OnboardingCard = ({
|
|||
onboardingData.project_id = settings.project_id;
|
||||
}
|
||||
|
||||
// Record the start time when user clicks Complete
|
||||
setProcessingStartTime(Date.now());
|
||||
onboardingMutation.mutate(onboardingData);
|
||||
setCurrentStep(0);
|
||||
};
|
||||
|
|
@ -211,30 +218,55 @@ const OnboardingCard = ({
|
|||
onValueChange={handleSetModelProvider}
|
||||
>
|
||||
<TabsList className="mb-4">
|
||||
<TabsTrigger
|
||||
value="openai"
|
||||
>
|
||||
<div className={cn("flex items-center justify-center gap-2 w-8 h-8 rounded-md", modelProvider === "openai" ? "bg-white" : "bg-muted")}>
|
||||
<OpenAILogo className={cn("w-4 h-4 shrink-0", modelProvider === "openai" ? "text-black" : "text-muted-foreground")} />
|
||||
<TabsTrigger value="openai">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center gap-2 w-8 h-8 rounded-md",
|
||||
modelProvider === "openai" ? "bg-white" : "bg-muted",
|
||||
)}
|
||||
>
|
||||
<OpenAILogo
|
||||
className={cn(
|
||||
"w-4 h-4 shrink-0",
|
||||
modelProvider === "openai"
|
||||
? "text-black"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
OpenAI
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="watsonx"
|
||||
>
|
||||
<div className={cn("flex items-center justify-center gap-2 w-8 h-8 rounded-md", modelProvider === "watsonx" ? "bg-[#1063FE]" : "bg-muted")}>
|
||||
<IBMLogo className={cn("w-4 h-4 shrink-0", modelProvider === "watsonx" ? "text-white" : "text-muted-foreground")} />
|
||||
<TabsTrigger value="watsonx">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center gap-2 w-8 h-8 rounded-md",
|
||||
modelProvider === "watsonx" ? "bg-[#1063FE]" : "bg-muted",
|
||||
)}
|
||||
>
|
||||
<IBMLogo
|
||||
className={cn(
|
||||
"w-4 h-4 shrink-0",
|
||||
modelProvider === "watsonx"
|
||||
? "text-white"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
IBM watsonx.ai
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="ollama"
|
||||
>
|
||||
<div className={cn("flex items-center justify-center gap-2 w-8 h-8 rounded-md", modelProvider === "ollama" ? "bg-white" : "bg-muted")}>
|
||||
<TabsTrigger value="ollama">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center gap-2 w-8 h-8 rounded-md",
|
||||
modelProvider === "ollama" ? "bg-white" : "bg-muted",
|
||||
)}
|
||||
>
|
||||
<OllamaLogo
|
||||
className={cn(
|
||||
"w-4 h-4 shrink-0",
|
||||
modelProvider === "ollama" ? "text-black" : "text-muted-foreground",
|
||||
modelProvider === "ollama"
|
||||
? "text-black"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -285,11 +317,13 @@ const OnboardingCard = ({
|
|||
</TooltipTrigger>
|
||||
{!isComplete && (
|
||||
<TooltipContent>
|
||||
{isLoadingModels ? "Loading models..." : (!!settings.llm_model &&
|
||||
!!settings.embedding_model &&
|
||||
!isDoclingHealthy
|
||||
? "docling-serve must be running to continue"
|
||||
: "Please fill in all required fields")}
|
||||
{isLoadingModels
|
||||
? "Loading models..."
|
||||
: !!settings.llm_model &&
|
||||
!!settings.embedding_model &&
|
||||
!isDoclingHealthy
|
||||
? "docling-serve must be running to continue"
|
||||
: "Please fill in all required fields"}
|
||||
</TooltipContent>
|
||||
)}
|
||||
</Tooltip>
|
||||
|
|
@ -303,11 +337,12 @@ const OnboardingCard = ({
|
|||
transition={{ duration: 0.4, ease: "easeInOut" }}
|
||||
>
|
||||
<AnimatedProviderSteps
|
||||
currentStep={currentStep}
|
||||
isCompleted={isCompleted}
|
||||
setCurrentStep={setCurrentStep}
|
||||
steps={STEP_LIST}
|
||||
/>
|
||||
currentStep={currentStep}
|
||||
isCompleted={isCompleted}
|
||||
setCurrentStep={setCurrentStep}
|
||||
steps={STEP_LIST}
|
||||
processingStartTime={processingStartTime}
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
|
|
|||
|
|
@ -35,4 +35,6 @@ export const TOTAL_ONBOARDING_STEPS = 3;
|
|||
export const ONBOARDING_STEP_KEY = "onboarding_current_step";
|
||||
|
||||
export const FILES_REGEX =
|
||||
/(?<=I'm uploading a document called ['"])[^'"]+\.[^.]+(?=['"]\. Here is its content:)/;
|
||||
/(?<=I'm uploading a document called ['"])[^'"]+\.[^.]+(?=['"]\. Here is its content:)/;
|
||||
|
||||
export const FILE_CONFIRMATION = "Confirm that you received this file.";
|
||||
Loading…
Add table
Reference in a new issue