diff --git a/frontend-web/src/components/workspace/agent-info-sidebar.tsx b/frontend-web/src/components/workspace/agent-info-sidebar.tsx index 27bd7640..803add70 100644 --- a/frontend-web/src/components/workspace/agent-info-sidebar.tsx +++ b/frontend-web/src/components/workspace/agent-info-sidebar.tsx @@ -43,7 +43,10 @@ export function AgentInfoSidebar({ onAskQuestion: (text: string) => void; disabled?: boolean; }) { - const [collapsed, setCollapsed] = useState(true); + // Expanded by default: the profile card is meant to be the agent's primary + // "expert info" panel, not a hidden drawer. Users can still collapse it on + // narrow screens via the header toggle. + const [collapsed, setCollapsed] = useState(false); const [detailSkillName, setDetailSkillName] = useState(null); const { skills } = useSkills(); const updateAgent = useUpdateAgent(); diff --git a/frontend-web/src/components/workspace/agent-welcome.tsx b/frontend-web/src/components/workspace/agent-welcome.tsx index d154becc..1fb8038d 100644 --- a/frontend-web/src/components/workspace/agent-welcome.tsx +++ b/frontend-web/src/components/workspace/agent-welcome.tsx @@ -1,39 +1,76 @@ -"use client"; - -import { BotIcon } from "lucide-react"; - -import { type Agent } from "@/core/agents"; -import { desensitize } from "@/lib/desensitize"; -import { cn } from "@/lib/utils"; - -export function AgentWelcome({ - className, - agent, - agentName, -}: { - className?: string; - agent: Agent | null | undefined; - agentName: string; -}) { - const displayName = desensitize(agent?.name ?? agentName); - const description = agent?.description - ? desensitize(agent.description) - : undefined; - - return ( -
-
- -
-
{displayName}
- {description && ( -

{description}

- )} -
- ); -} +"use client"; + +import { BotIcon } from "lucide-react"; + +import { type Agent } from "@/core/agents"; +import { desensitize } from "@/lib/desensitize"; +import { cn } from "@/lib/utils"; + +/** + * Landing (home) hero shown above the input box before the first message of an + * agent conversation. Mirrors the qclaw landing screen: centered avatar, a + * "Hi,我是{name}" greeting, the agent's one-line description as a slogan, and + * the agent's admin-configured common questions surfaced as clickable starter + * pills. Clicking a pill sends it as the opening message via `onAskQuestion`. + */ +export function AgentWelcome({ + className, + agent, + agentName, + onAskQuestion, + disabled, +}: { + className?: string; + agent: Agent | null | undefined; + agentName: string; + onAskQuestion?: (text: string) => void; + disabled?: boolean; +}) { + const displayName = desensitize(agent?.name ?? agentName); + const description = agent?.description + ? desensitize(agent.description) + : undefined; + const questions = (agent?.common_questions ?? []).filter( + (q) => q.trim().length > 0, + ); + + return ( +
+
+ +
+
+ Hi,我是{displayName} +
+ {description && ( +

+ {description} +

+ )} + {onAskQuestion && questions.length > 0 && ( +
+ {questions.slice(0, 6).map((question, index) => ( + + ))} +
+ )} +
+ ); +} diff --git a/frontend-web/src/pages/AgentChatPage.tsx b/frontend-web/src/pages/AgentChatPage.tsx index e26bc612..1cf155c2 100644 --- a/frontend-web/src/pages/AgentChatPage.tsx +++ b/frontend-web/src/pages/AgentChatPage.tsx @@ -268,7 +268,16 @@ export default function AgentChatPage() { context={settings.context} extraHeader={ isLandingState && ( - + + handleSubmit({ text, files: [] }) + } + disabled={ + env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true" + } + /> ) } disabled={env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true"}