mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-01 07:03:02 +00:00
fix(chat): describe general chat and deep research on the chat home (#49531)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
8c46b2c0d6
commit
28679bb9c3
8 changed files with 68 additions and 13 deletions
|
|
@ -134,6 +134,47 @@ beforeEach(() => {
|
|||
});
|
||||
afterEach(() => vi.unstubAllGlobals());
|
||||
|
||||
it("should switch the composer placeholder with deep research on home and in a conversation", async () => {
|
||||
const user = userEvent.setup();
|
||||
const home = renderChat();
|
||||
await screen.findByRole("button", { name: "research-chat" });
|
||||
const homeEditor = screen.getByRole("textbox", { name: "Message" });
|
||||
expect(homeEditor).toHaveAttribute("placeholder", "Ask a question, attach a file, or paste something to work on…");
|
||||
|
||||
const enableResearch = async () => {
|
||||
await user.click(screen.getByRole("button", { name: "Connect tools" }));
|
||||
await user.click(await screen.findByRole("button", { name: "Deep research", exact: true }));
|
||||
};
|
||||
await enableResearch();
|
||||
expect(homeEditor).toHaveAttribute("placeholder", "What should I research on the web?");
|
||||
await user.click(screen.getByRole("button", { name: "Turn off deep research" }));
|
||||
expect(homeEditor).toHaveAttribute("placeholder", "Ask a question, attach a file, or paste something to work on…");
|
||||
|
||||
home.unmount();
|
||||
const conversationId = "saved-chat";
|
||||
const history: Conversation[] = [
|
||||
{
|
||||
id: conversationId,
|
||||
title: "Saved chat",
|
||||
model: "research-chat",
|
||||
messages: [{ id: "saved-message", role: "user", content: "Previous question", timestamp: 1 }],
|
||||
mcpServerNames: [],
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
},
|
||||
];
|
||||
localStorage.setItem(storageKey, JSON.stringify(history));
|
||||
renderChat(conversationId);
|
||||
await screen.findByRole("button", { name: "research-chat" });
|
||||
const conversationEditor = screen.getByRole("textbox", { name: "Message" });
|
||||
expect(conversationEditor).toHaveAttribute("placeholder", "Send a message...");
|
||||
|
||||
await enableResearch();
|
||||
expect(conversationEditor).toHaveAttribute("placeholder", "What should I research on the web?");
|
||||
await user.click(screen.getByRole("button", { name: "Turn off deep research" }));
|
||||
expect(conversationEditor).toHaveAttribute("placeholder", "Send a message...");
|
||||
});
|
||||
|
||||
async function startResearch(withTools = true) {
|
||||
const user = userEvent.setup();
|
||||
await screen.findByRole("button", { name: "research-chat" });
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ const ON_TOTAL_LATENCY_INDEX = 24;
|
|||
async function sendOneMessage(onUrlUpdate?: OnUrlUpdateFunction): Promise<void> {
|
||||
renderWithProviders(<ChatConversationPage />, { onUrlUpdate });
|
||||
expect(await screen.findByRole("button", { name: /gpt-5\.4-mini/ })).toBeInTheDocument();
|
||||
fireEvent.change(screen.getByPlaceholderText("Describe a change, paste an error, or ask a question…"), {
|
||||
fireEvent.change(screen.getByPlaceholderText("Ask a question, attach a file, or paste something to work on…"), {
|
||||
target: { value: "How much did this cost?" },
|
||||
});
|
||||
fireEvent.click(screen.getByRole("button", { name: "Send" }));
|
||||
|
|
|
|||
|
|
@ -505,9 +505,10 @@ export default function ChatConversationPage() {
|
|||
|
||||
const inputBar = (inConversation: boolean) => {
|
||||
const hint = mode === "chat" || background.pending ? backgroundHint() : null;
|
||||
const chatPlaceholder = inConversation
|
||||
const defaultPlaceholder = inConversation
|
||||
? "Send a message..."
|
||||
: "Describe a change, paste an error, or ask a question…";
|
||||
: "Ask a question, attach a file, or paste something to work on…";
|
||||
const chatPlaceholder = research ? "What should I research on the web?" : defaultPlaceholder;
|
||||
const preparing = isLoadingModels || isReadingAttachments;
|
||||
const researchBlocked = research && !canResearch;
|
||||
const submitDisabled =
|
||||
|
|
@ -718,6 +719,7 @@ export default function ChatConversationPage() {
|
|||
{showBlankState ? (
|
||||
<MoyaiChatHome
|
||||
imageMode={mode === "image"}
|
||||
researchMode={research}
|
||||
draft={inputText}
|
||||
busy={isStreaming}
|
||||
conversations={conversations}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ describe("chat page URL state with ChatShellProvider", () => {
|
|||
|
||||
expect(await screen.findByRole("button", { name: /gpt-5\.4-mini/ })).toBeInTheDocument();
|
||||
act(() => {
|
||||
fireEvent.change(screen.getByPlaceholderText("Describe a change, paste an error, or ask a question…"), {
|
||||
fireEvent.change(screen.getByPlaceholderText("Ask a question, attach a file, or paste something to work on…"), {
|
||||
target: { value: "How much did this cost?" },
|
||||
});
|
||||
});
|
||||
|
|
@ -87,9 +87,9 @@ describe("chat page URL state with ChatShellProvider", () => {
|
|||
await waitFor(() => expect(window.location.search).toBe(""));
|
||||
|
||||
expect(
|
||||
await screen.findByPlaceholderText("Describe a change, paste an error, or ask a question…"),
|
||||
await screen.findByPlaceholderText("Ask a question, attach a file, or paste something to work on…"),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole("heading", { level: 1, name: "What are we building?" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("heading", { level: 1, name: "What are we working on?" })).toBeInTheDocument();
|
||||
expect(screen.queryByText("The estimated cost is one cent.")).not.toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: "How much did this cost?" })).toBeInTheDocument();
|
||||
expect(window.location.pathname).toBe("/chat");
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ Show available providers in a single-select dropdown beside model search. “All
|
|||
```tsx
|
||||
// Page/greeting heading
|
||||
<header className="moyai-chat-home-header">
|
||||
<h1>What are we building?</h1>
|
||||
<h1>What are we working on?</h1>
|
||||
</header> // Moyai: 500 weight, clamp(32px, 3.4vw, 46px), 1.13 line-height
|
||||
|
||||
// Section heading (panel titles: "Your API Keys", "Your Usage")
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ function composerProps(overrides: Partial<ComponentProps<typeof MoyaiChatCompose
|
|||
onChange: vi.fn(),
|
||||
onSubmit: vi.fn(),
|
||||
onCancel: vi.fn(),
|
||||
placeholder: "Describe a change, paste an error, or ask a question…",
|
||||
placeholder: "Ask a question, attach a file, or paste something to work on…",
|
||||
isLoading: false,
|
||||
submitDisabled: false,
|
||||
submitLabel: "Send",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ function homeProps(overrides: Partial<ComponentProps<typeof MoyaiChatHome>> = {}
|
|||
return {
|
||||
children: <span>Chat composer</span>,
|
||||
imageMode: false,
|
||||
researchMode: false,
|
||||
draft: "",
|
||||
busy: false,
|
||||
conversations: [],
|
||||
|
|
@ -24,12 +25,17 @@ function conversation(id: string, updatedAt: number): Conversation {
|
|||
describe("MoyaiChatHome", () => {
|
||||
it("should render the Moyai welcome and composer", () => {
|
||||
render(<MoyaiChatHome {...homeProps()} />);
|
||||
expect(screen.getByRole("heading", { level: 1, name: "What are we building?" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("heading", { level: 1, name: "What are we working on?" })).toBeInTheDocument();
|
||||
expect(screen.getByText("Chat composer")).toBeInTheDocument();
|
||||
expect(screen.getByRole("heading", { name: "Recent chats" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("status")).toHaveTextContent("No recent chats in this browser yet.");
|
||||
});
|
||||
|
||||
it("should render the research welcome when research mode is enabled", () => {
|
||||
render(<MoyaiChatHome {...homeProps({ researchMode: true })} />);
|
||||
expect(screen.getByRole("heading", { level: 1, name: "What should we research?" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show the three most recently updated chats and open the selected one", () => {
|
||||
const conversations = [
|
||||
conversation("first", 1),
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ const starters = [
|
|||
export default function MoyaiChatHome({
|
||||
children,
|
||||
imageMode,
|
||||
researchMode,
|
||||
draft,
|
||||
busy,
|
||||
conversations,
|
||||
|
|
@ -31,6 +32,7 @@ export default function MoyaiChatHome({
|
|||
}: {
|
||||
children: ReactNode;
|
||||
imageMode: boolean;
|
||||
researchMode: boolean;
|
||||
draft: string;
|
||||
busy: boolean;
|
||||
conversations: Conversation[];
|
||||
|
|
@ -44,11 +46,15 @@ export default function MoyaiChatHome({
|
|||
<div className="moyai-chat-home-content">
|
||||
<header className="moyai-chat-home-header">
|
||||
<h1>
|
||||
{imageMode ? (
|
||||
"What are we creating?"
|
||||
) : (
|
||||
{imageMode && "What are we creating?"}
|
||||
{!imageMode && researchMode && (
|
||||
<>
|
||||
What are we <span>building?</span>
|
||||
What should we <span>research?</span>
|
||||
</>
|
||||
)}
|
||||
{!imageMode && !researchMode && (
|
||||
<>
|
||||
What are we <span>working on?</span>
|
||||
</>
|
||||
)}
|
||||
</h1>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue