From dfa4eb0c1a4582ae2fc0472c5b476f6a9cec8212 Mon Sep 17 00:00:00 2001 From: DanielWalnut <45447813+hetaoBackend@users.noreply.github.com> Date: Sun, 10 May 2026 15:10:44 +0800 Subject: [PATCH] [codex] fix follow-up suggestions layout (#2836) * fix follow-up suggestions layout * fix agent chat welcome layout transition --------- Co-authored-by: Willem Jiang --- .../[agent_name]/chats/[thread_id]/page.tsx | 82 ++++++++++++------- .../app/workspace/chats/[thread_id]/page.tsx | 57 ++++++++----- .../src/components/workspace/input-box.tsx | 33 +++----- .../workspace/messages/message-list.tsx | 3 +- 4 files changed, 101 insertions(+), 74 deletions(-) diff --git a/frontend/src/app/workspace/agents/[agent_name]/chats/[thread_id]/page.tsx b/frontend/src/app/workspace/agents/[agent_name]/chats/[thread_id]/page.tsx index cfd444e4d..8627762b0 100644 --- a/frontend/src/app/workspace/agents/[agent_name]/chats/[thread_id]/page.tsx +++ b/frontend/src/app/workspace/agents/[agent_name]/chats/[thread_id]/page.tsx @@ -2,7 +2,7 @@ import { BotIcon, PlusSquare } from "lucide-react"; import { useParams, useRouter } from "next/navigation"; -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import type { PromptInputMessage } from "@/components/ai-elements/prompt-input"; import { Button } from "@/components/ui/button"; @@ -14,7 +14,6 @@ import { InputBox } from "@/components/workspace/input-box"; import { MessageList, MESSAGE_LIST_DEFAULT_PADDING_BOTTOM, - MESSAGE_LIST_FOLLOWUPS_EXTRA_PADDING_BOTTOM, } from "@/components/workspace/messages"; import { ThreadContext } from "@/components/workspace/messages/context"; import { ThreadTitle } from "@/components/workspace/thread-title"; @@ -34,7 +33,6 @@ import { cn } from "@/lib/utils"; export default function AgentChatPage() { const { t } = useI18n(); - const [showFollowups, setShowFollowups] = useState(false); const router = useRouter(); const { agent_name } = useParams<{ @@ -45,6 +43,10 @@ export default function AgentChatPage() { const { threadId, setThreadId, isNewThread, setIsNewThread, isMock } = useThreadChat(); + // `isNewThread` gates history/token-usage fetches until the backend creates + // the thread. `isWelcomeMode` controls only the centered welcome layout, so + // it can flip immediately on submit without triggering eager history loads. + const [isWelcomeMode, setIsWelcomeMode] = useState(isNewThread); const [settings, setSettings] = useThreadSettings(threadId); const [localSettings, setLocalSettings] = useLocalSettings(); const { tokenUsageEnabled } = useModels(); @@ -55,6 +57,11 @@ export default function AgentChatPage() { const backendTokenUsage = threadTokenUsageToTokenUsage(threadTokenUsage.data); const { showNotification } = useNotification(); + + useEffect(() => { + setIsWelcomeMode(isNewThread); + }, [isNewThread]); + const { thread, pendingUsageMessages, @@ -66,6 +73,9 @@ export default function AgentChatPage() { threadId: isNewThread ? undefined : threadId, context: { ...settings.context, agent_name: agent_name }, isMock, + onSend: () => { + setIsWelcomeMode(false); + }, onStart: (createdThreadId) => { setThreadId(createdThreadId); setIsNewThread(false); @@ -105,13 +115,10 @@ export default function AgentChatPage() { await thread.stop(); }, [thread]); - const messageListPaddingBottom = showFollowups - ? MESSAGE_LIST_DEFAULT_PADDING_BOTTOM + - MESSAGE_LIST_FOLLOWUPS_EXTRA_PADDING_BOTTOM - : undefined; const tokenUsageInlineMode = tokenUsageEnabled ? localSettings.tokenUsage.inlineMode : "off"; + const hasTodos = (thread.values.todos?.length ?? 0) > 0; return ( @@ -120,7 +127,7 @@ export default function AgentChatPage() {
-
+
-
+
-
-
-
+ )} ) } disabled={env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true"} onContextChange={(context) => setSettings("context", context)} - onFollowupsVisibilityChange={setShowFollowups} onSubmit={handleSubmit} onStop={handleStop} /> diff --git a/frontend/src/app/workspace/chats/[thread_id]/page.tsx b/frontend/src/app/workspace/chats/[thread_id]/page.tsx index a04fe994d..ed7d91c68 100644 --- a/frontend/src/app/workspace/chats/[thread_id]/page.tsx +++ b/frontend/src/app/workspace/chats/[thread_id]/page.tsx @@ -14,7 +14,6 @@ import { InputBox } from "@/components/workspace/input-box"; import { MessageList, MESSAGE_LIST_DEFAULT_PADDING_BOTTOM, - MESSAGE_LIST_FOLLOWUPS_EXTRA_PADDING_BOTTOM, } from "@/components/workspace/messages"; import { ThreadContext } from "@/components/workspace/messages/context"; import { ThreadTitle } from "@/components/workspace/thread-title"; @@ -33,7 +32,6 @@ import { cn } from "@/lib/utils"; export default function ChatPage() { const { t } = useI18n(); - const [showFollowups, setShowFollowups] = useState(false); const { threadId, setThreadId, isNewThread, setIsNewThread, isMock } = useThreadChat(); // `isNewThread` tracks whether the backend has the thread yet — gates the @@ -119,13 +117,10 @@ export default function ChatPage() { await thread.stop(); }, [thread]); - const messageListPaddingBottom = showFollowups - ? MESSAGE_LIST_DEFAULT_PADDING_BOTTOM + - MESSAGE_LIST_FOLLOWUPS_EXTRA_PADDING_BOTTOM - : undefined; const tokenUsageInlineMode = tokenUsageEnabled ? localSettings.tokenUsage.inlineMode : "off"; + const hasTodos = (thread.values.todos?.length ?? 0) > 0; return ( @@ -159,19 +154,24 @@ export default function ChatPage() {
-
+
-
+
-
-
-
+ )} {mountedRef.current ? ( setSettings("context", context) } - onFollowupsVisibilityChange={setShowFollowups} onSubmit={handleSubmit} onStop={handleStop} /> @@ -224,7 +236,8 @@ export default function ChatPage() {