Unify loading goose messages and usechatstream determines chat state (#5306)
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { SearchView } from './conversation/SearchView';
|
||||
import LoadingGoose from './LoadingGoose';
|
||||
import { getThinkingMessage } from '../types/message';
|
||||
import PopularChatTopics from './PopularChatTopics';
|
||||
import ProgressiveMessageList from './ProgressiveMessageList';
|
||||
import { MainPanelLayout } from './Layout/MainPanelLayout';
|
||||
@@ -23,6 +22,7 @@ import { scanRecipe } from '../recipe';
|
||||
import { useCostTracking } from '../hooks/useCostTracking';
|
||||
import RecipeActivities from './recipes/RecipeActivities';
|
||||
import { useToolCount } from './alerts/useToolCount';
|
||||
import { getThinkingMessage } from '../types/message';
|
||||
|
||||
interface BaseChatProps {
|
||||
setChat: (chat: ChatType) => void;
|
||||
@@ -179,13 +179,6 @@ function BaseChatContent({
|
||||
|
||||
const initialPrompt = messages.length == 0 && recipe?.prompt ? recipe.prompt : '';
|
||||
|
||||
// Map chatState to LoadingGoose message
|
||||
const getLoadingMessage = (): string | undefined => {
|
||||
if (messages.length === 0 && chatState === ChatState.Thinking) {
|
||||
return 'loading conversation...';
|
||||
}
|
||||
return getThinkingMessage(messages[messages.length - 1]);
|
||||
};
|
||||
return (
|
||||
<div className="h-full flex flex-col min-h-0">
|
||||
<h2>Warning: BaseChat2!</h2>
|
||||
@@ -255,10 +248,16 @@ function BaseChatContent({
|
||||
) : null}
|
||||
</ScrollArea>
|
||||
|
||||
{/* Fixed loading indicator at bottom left of chat container */}
|
||||
{chatState !== ChatState.Idle && !sessionLoadError && (
|
||||
<div className="absolute bottom-1 left-4 z-20 pointer-events-none">
|
||||
<LoadingGoose message={getLoadingMessage()} chatState={chatState} />
|
||||
<LoadingGoose
|
||||
chatState={chatState}
|
||||
message={
|
||||
messages.length > 0
|
||||
? getThinkingMessage(messages[messages.length - 1])
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -8,18 +8,29 @@ interface LoadingGooseProps {
|
||||
chatState?: ChatState;
|
||||
}
|
||||
|
||||
const STATE_MESSAGES: Record<ChatState, string> = {
|
||||
[ChatState.LoadingConversation]: 'loading conversation...',
|
||||
[ChatState.Thinking]: 'goose is thinking…',
|
||||
[ChatState.Streaming]: 'goose is working on it…',
|
||||
[ChatState.WaitingForUserInput]: 'goose is waiting…',
|
||||
[ChatState.Compacting]: 'goose is compacting the conversation...',
|
||||
[ChatState.Idle]: 'goose is working on it…',
|
||||
};
|
||||
|
||||
const STATE_ICONS: Record<ChatState, React.ReactNode> = {
|
||||
[ChatState.LoadingConversation]: <AnimatedIcons className="flex-shrink-0" cycleInterval={600} />,
|
||||
[ChatState.Thinking]: <AnimatedIcons className="flex-shrink-0" cycleInterval={600} />,
|
||||
[ChatState.Streaming]: <FlyingBird className="flex-shrink-0" cycleInterval={150} />,
|
||||
[ChatState.WaitingForUserInput]: (
|
||||
<AnimatedIcons className="flex-shrink-0" cycleInterval={600} variant="waiting" />
|
||||
),
|
||||
[ChatState.Compacting]: <AnimatedIcons className="flex-shrink-0" cycleInterval={600} />,
|
||||
[ChatState.Idle]: <GooseLogo size="small" hover={false} />,
|
||||
};
|
||||
|
||||
const LoadingGoose = ({ message, chatState = ChatState.Idle }: LoadingGooseProps) => {
|
||||
// Determine the appropriate message based on state
|
||||
const getLoadingMessage = () => {
|
||||
if (message) return message; // Custom message takes priority
|
||||
|
||||
if (chatState === ChatState.Thinking) return 'goose is thinking…';
|
||||
if (chatState === ChatState.Streaming) return 'goose is working on it…';
|
||||
if (chatState === ChatState.WaitingForUserInput) return 'goose is waiting…';
|
||||
|
||||
// Default fallback
|
||||
return 'goose is working on it…';
|
||||
};
|
||||
const displayMessage = message || STATE_MESSAGES[chatState];
|
||||
const icon = STATE_ICONS[chatState];
|
||||
|
||||
return (
|
||||
<div className="w-full animate-fade-slide-up">
|
||||
@@ -27,16 +38,8 @@ const LoadingGoose = ({ message, chatState = ChatState.Idle }: LoadingGooseProps
|
||||
data-testid="loading-indicator"
|
||||
className="flex items-center gap-2 text-xs text-textStandard py-2"
|
||||
>
|
||||
{chatState === ChatState.Thinking ? (
|
||||
<AnimatedIcons className="flex-shrink-0" cycleInterval={600} />
|
||||
) : chatState === ChatState.Streaming ? (
|
||||
<FlyingBird className="flex-shrink-0" cycleInterval={150} />
|
||||
) : chatState === ChatState.WaitingForUserInput ? (
|
||||
<AnimatedIcons className="flex-shrink-0" cycleInterval={600} variant="waiting" />
|
||||
) : (
|
||||
<GooseLogo size="small" hover={false} />
|
||||
)}
|
||||
{getLoadingMessage()}
|
||||
{icon}
|
||||
{displayMessage}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user