Skip to content

Agent Mode UI Tweaks #4779

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 29 additions & 29 deletions gui/src/components/mainInput/Lump/BlockSettingsTopToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,38 +98,38 @@ export function BlockSettingsTopToolbar(props: BlockSettingsTopToolbarProps) {
};

return (
<div className="flex w-full items-center justify-between">
<div className="xs:flex hidden items-center justify-center text-gray-400">
<BlockSettingsToolbarIcon
icon={isExpanded ? ChevronLeftIcon : EllipsisHorizontalIcon}
tooltip={isExpanded ? "Collapse sections" : "Expand sections"}
isSelected={false}
onClick={handleEllipsisClick}
/>
<div
className="flex overflow-hidden transition-all duration-200"
style={{ width: isExpanded ? `160px` : "0px" }}
>
<div className="flex">
{sections.map((section) => (
<BlockSettingsToolbarIcon
key={section.id}
icon={section.icon}
tooltip={section.tooltip}
isSelected={props.selectedSection === section.id}
onClick={() =>
props.setSelectedSection(
props.selectedSection === section.id ? null : section.id,
)
}
/>
))}
<div className="flex items-center justify-between">
<div>
<div className="xs:flex hidden items-center justify-center text-gray-400">
<BlockSettingsToolbarIcon
icon={isExpanded ? ChevronLeftIcon : EllipsisHorizontalIcon}
tooltip={isExpanded ? "Collapse sections" : "Expand sections"}
isSelected={false}
onClick={handleEllipsisClick}
/>
<div
className="flex overflow-hidden transition-all duration-200"
style={{ width: isExpanded ? `160px` : "0px" }}
>
<div className="flex">
{sections.map((section) => (
<BlockSettingsToolbarIcon
key={section.id}
icon={section.icon}
tooltip={section.tooltip}
isSelected={props.selectedSection === section.id}
onClick={() =>
props.setSelectedSection(
props.selectedSection === section.id ? null : section.id,
)
}
/>
))}
</div>
</div>
</div>
</div>
<div className="ml-auto">
<AssistantSelect />
</div>
<AssistantSelect />
</div>
);
}
23 changes: 16 additions & 7 deletions gui/src/components/modelSelection/ModeSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "@heroicons/react/24/outline";
import { MessageModes } from "core";
import { modelSupportsTools } from "core/llm/autodetect";
import { useEffect } from "react";
import { useEffect, useMemo } from "react";
import styled from "styled-components";
import { defaultBorderRadius, lightGray, vscInputBackground } from "..";
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
Expand All @@ -25,6 +25,7 @@ import {
getMetaKeyLabel,
isJetBrains,
} from "../../util";
import Shortcut from "../gui/Shortcut";

const StyledListboxButton = styled(Listbox.Button)`
font-family: inherit;
Expand Down Expand Up @@ -81,7 +82,13 @@ function ModeSelect() {
const mode = useAppSelector(selectCurrentMode);
const selectedModel = useAppSelector(selectDefaultModel);
const agentModeSupported = selectedModel && modelSupportsTools(selectedModel);
const jetbrains = isJetBrains();

const jetbrains = useMemo(() => {
return isJetBrains();
}, []);
const metaKeyLabel = useMemo(() => {
return getMetaKeyLabel();
}, []);

const getModeIcon = (mode: MessageModes) => {
switch (mode) {
Expand Down Expand Up @@ -133,7 +140,9 @@ function ModeSelect() {
className="flex items-center gap-1 rounded-full px-2 py-0.5 text-gray-400 transition-colors duration-200"
>
{getModeIcon(mode)}
<span>{mode.charAt(0).toUpperCase() + mode.slice(1)}</span>
<span className="hidden sm:block">
{mode.charAt(0).toUpperCase() + mode.slice(1)}
</span>
<ChevronDownIcon
className="h-2 w-2 flex-shrink-0"
aria-hidden="true"
Expand All @@ -157,22 +166,22 @@ function ModeSelect() {
<StyledListboxOption value="chat">
<ChatBubbleLeftIcon className="h-3 w-3" />
<span className="font-semibold">Chat</span>
<ShortcutText>{getMetaKeyLabel()}L</ShortcutText>
<ShortcutText>{metaKeyLabel}L</ShortcutText>
{mode === "chat" && <CheckIcon className="ml-auto h-3 w-3" />}
</StyledListboxOption>

{!jetbrains && (
<StyledListboxOption value="edit">
<PencilIcon className="h-3 w-3" />
<span className="font-semibold">Edit</span>
<ShortcutText>{getMetaKeyLabel()}I</ShortcutText>
<ShortcutText>{metaKeyLabel}I</ShortcutText>
{mode === "edit" && <CheckIcon className="ml-auto h-3 w-3" />}
</StyledListboxOption>
)}

<div className="text-lightgray px-2 py-1">
{getMetaKeyLabel()}
<span>.</span> for next mode
<Shortcut>{metaKeyLabel}</Shortcut>
<Shortcut>.</Shortcut> for next mode
</div>
</StyledListboxOptions>
</div>
Expand Down
22 changes: 17 additions & 5 deletions gui/src/components/modelSelection/platform/AssistantSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ import { useContext, useEffect, useRef } from "react";
import { useAuth } from "../../../context/Auth";
import { IdeMessengerContext } from "../../../context/IdeMessenger";
import { cycleProfile } from "../../../redux";
import { useAppDispatch } from "../../../redux/hooks";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
import { fontSize, isMetaEquivalentKeyPressed } from "../../../util";
import PopoverTransition from "../../mainInput/InputToolbar/bottom/PopoverTransition";
import AssistantIcon from "./AssistantIcon";
import { AssistantSelectOptions } from "./AssistantSelectOptions";

function AssistantSelectButton(props: { selectedProfile: ProfileDescription }) {
const isLumpToolbarExpanded = useAppSelector(
(state) => state.ui.isBlockSettingsToolbarExpanded,
);
return (
<div className="flex max-w-[50vw] items-center gap-0.5">
<div className="mr-1 h-3 w-3 flex-shrink-0 select-none">
<AssistantIcon size={3} assistant={props.selectedProfile} />
<AssistantIcon assistant={props.selectedProfile} />
</div>
<span className="select-none truncate">
<span
className={`select-none truncate ${isLumpToolbarExpanded ? "xs:hidden sm:block" : ""}`}
>
{props.selectedProfile.title}
</span>
<ChevronDownIcon
Expand Down Expand Up @@ -68,7 +73,7 @@ export default function AssistantSelect() {
orgSlug: selectedOrganization?.slug,
});
}}
className="hover:bg flex cursor-pointer select-none items-center gap-1 whitespace-nowrap text-gray-400"
className="flex cursor-pointer select-none items-center gap-1 whitespace-nowrap text-gray-400"
style={{ fontSize: fontSize(-3) }}
>
<PlusIcon className="h-3 w-3 select-none" /> Create your first assistant
Expand All @@ -89,7 +94,14 @@ export default function AssistantSelect() {
</Popover.Button>

<PopoverTransition>
<Popover.Panel className="bg-vsc-input-background absolute right-0 top-full z-[1000] mr-1 mt-1 flex min-w-[200px] max-w-[90vw] cursor-default flex-row overflow-hidden rounded-md border-2 border-zinc-600 p-0">
<Popover.Panel
className="bg-vsc-input-background flex min-w-[200px] max-w-[90vw] cursor-default flex-row rounded-md border-[0.5px] border-solid border-zinc-600 p-0"
style={{
position: "absolute",
right: 0,
zIndex: 1000,
}}
>
<AssistantSelectOptions
onClose={() => {
if (buttonRef.current) {
Expand Down
49 changes: 21 additions & 28 deletions gui/src/pages/config/KeyboardShortcuts.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useMemo } from "react";
import styled from "styled-components";
import {
defaultBorderRadius,
Expand All @@ -7,16 +8,6 @@ import {
import { ToolTip } from "../../components/gui/Tooltip";
import { getPlatform, isJetBrains } from "../../util";

const GridDiv = styled.div`
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-gap: 1rem;
padding: 1rem 0;
justify-items: center;
align-items: center;
overflow-x: hidden;
`;

const StyledKeyDiv = styled.div`
border: 0.5px solid ${lightGray};
border-radius: ${defaultBorderRadius};
Expand Down Expand Up @@ -64,9 +55,9 @@ interface KeyboardShortcutProps {
function KeyboardShortcut(props: KeyboardShortcutProps) {
const shortcut = getPlatform() === "mac" ? props.mac : props.windows;
return (
<div className="flex w-full items-center justify-between gap-x-4">
<span className="text-xs">{props.description}</span>
<div className="float-right flex gap-2">
<div className="flex w-full flex-wrap items-center justify-between gap-x-4 gap-y-1">
<span className="max-w-60 text-xs">{props.description}:</span>
<div className="flex flex-1 flex-row items-center justify-end gap-1.5">
{shortcut.split(" ").map((key, i) => {
return <KeyDiv key={i} text={key}></KeyDiv>;
})}
Expand Down Expand Up @@ -201,23 +192,25 @@ const jetbrainsShortcuts: KeyboardShortcutProps[] = [
];

function KeyboardShortcuts() {
const shortcuts = useMemo(() => {
return isJetBrains() ? jetbrainsShortcuts : vscodeShortcuts;
}, []);

return (
<div>
<div className="flex max-w-[400px] flex-col">
<h3 className="mx-auto mb-1 text-xl">Keyboard shortcuts</h3>
<GridDiv>
{(isJetBrains() ? jetbrainsShortcuts : vscodeShortcuts).map(
(shortcut, i) => {
return (
<KeyboardShortcut
key={i}
mac={shortcut.mac}
windows={shortcut.windows}
description={shortcut.description}
/>
);
},
)}
</GridDiv>
<div className="flex flex-col items-center justify-center gap-x-3 gap-y-3 p-1">
{shortcuts.map((shortcut, i) => {
return (
<KeyboardShortcut
key={i}
mac={shortcut.mac}
windows={shortcut.windows}
description={shortcut.description}
/>
);
})}
</div>
</div>
);
}
Expand Down
18 changes: 10 additions & 8 deletions gui/src/pages/config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,32 @@ function ConfigPage() {
id: "settings",
label: "Settings",
component: <UserSettingsForm />,
icon: <Cog6ToothIcon className="h-4 w-4 flex-shrink-0" />,
icon: <Cog6ToothIcon className="xs:h-4 xs:w-4 h-3 w-3 flex-shrink-0" />,
},
{
id: "indexing",
label: "Indexing",
component: <IndexingSettingsSection />,
icon: <CircleStackIcon className="h-4 w-4 flex-shrink-0" />,
icon: <CircleStackIcon className="xs:h-4 xs:w-4 h-3 w-3 flex-shrink-0" />,
},
{
id: "help",
label: "Help",
component: <HelpCenterSection />,
icon: <QuestionMarkCircleIcon className="h-4 w-4 flex-shrink-0" />,
icon: (
<QuestionMarkCircleIcon className="xs:h-4 xs:w-4 h-3 w-3 flex-shrink-0" />
),
},
{
id: "shortcuts",
label: "Shortcuts",
component: <KeyboardShortcuts />,
icon: <AcademicCapIcon className="h-4 w-4 flex-shrink-0" />,
icon: <AcademicCapIcon className="xs:h-4 xs:w-4 h-3 w-3 flex-shrink-0" />,
},
];

return (
<div className="flex h-full flex-col">
<div className="flex h-full flex-col overflow-y-auto">
<div className="bg-vsc-background sticky top-0 z-10">
<PageHeader
showBorder
Expand All @@ -65,14 +67,14 @@ function ConfigPage() {
/>

{/* Tab Headers */}
<div className="grid w-full grid-cols-2 border-0 border-b-[1px] border-solid border-b-zinc-700 sm:flex sm:justify-center">
<div className="grid grid-cols-2 border-0 border-b-[1px] border-solid border-b-zinc-700 p-0.5 sm:flex sm:justify-center md:gap-x-2">
{tabs.map((tab) => (
<div
style={{
fontSize: fontSize(-2),
}}
key={tab.id}
className={`hover:bg-vsc-input-background flex cursor-pointer items-center justify-center gap-2 rounded-md px-4 py-2 ${
className={`hover:bg-vsc-input-background flex cursor-pointer items-center justify-center gap-1.5 rounded-md px-2 py-2 ${
activeTab === tab.id ? "" : "text-gray-400"
}`}
onClick={() => setActiveTab(tab.id)}
Expand All @@ -85,7 +87,7 @@ function ConfigPage() {
</div>

{/* Tab Content */}
<div className="flex-1 overflow-y-auto overflow-x-hidden px-4">
<div className="flex-1 overflow-y-auto px-4">
{tabs.find((tab) => tab.id === activeTab)?.component}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion gui/src/pages/gui/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export function Chat() {

<StepsDiv
ref={stepsDivRef}
className={`overflow-y-scroll ${showPageHeader ? "" : "pt-[8px]"} ${showScrollbar ? "thin-scrollbar" : "no-scrollbar"} ${history.length > 0 ? "flex-1" : ""}`}
className={`mt-[2px] overflow-y-scroll ${showPageHeader ? "" : "pt-[8px]"} ${showScrollbar ? "thin-scrollbar" : "no-scrollbar"} ${history.length > 0 ? "flex-1" : ""}`}
>
{highlights}
{history.map((item, index: number) => (
Expand Down
Loading