-
- {t('chat.add.assistant.title')}
-
-
+
+
{t('chat.add.assistant.title')}
)
}
diff --git a/src/renderer/src/pages/home/Tabs/components/shared.tsx b/src/renderer/src/pages/home/Tabs/components/shared.tsx
deleted file mode 100644
index 2ef0278984..0000000000
--- a/src/renderer/src/pages/home/Tabs/components/shared.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-import { cn } from '@heroui/react'
-import type { ComponentPropsWithoutRef, ComponentPropsWithRef } from 'react'
-import { useMemo } from 'react'
-import styled from 'styled-components'
-
-export const ListItem = ({ children, className, ...props }: ComponentPropsWithoutRef<'div'>) => {
- return (
-
- {children}
-
- )
-}
-export const ListItemNameContainer = ({ children, className, ...props }: ComponentPropsWithoutRef<'div'>) => {
- return (
-
- {children}
-
- )
-}
-
-// This component involves complex animations and will not be migrated for now.
-export const ListItemName = styled.div`
- display: -webkit-box;
- -webkit-line-clamp: 1;
- -webkit-box-orient: vertical;
- overflow: hidden;
- font-size: 14px;
- position: relative;
- will-change: background-position, width;
-
- --color-shimmer-mid: var(--color-text-1);
- --color-shimmer-end: color-mix(in srgb, var(--color-text-1) 25%, transparent);
-
- &.shimmer {
- background: linear-gradient(to left, var(--color-shimmer-end), var(--color-shimmer-mid), var(--color-shimmer-end));
- background-size: 200% 100%;
- background-clip: text;
- color: transparent;
- animation: shimmer 3s linear infinite;
- }
-
- &.typing {
- display: block;
- -webkit-line-clamp: unset;
- -webkit-box-orient: unset;
- white-space: nowrap;
- overflow: hidden;
- animation: typewriter 0.5s steps(40, end);
- }
-
- @keyframes shimmer {
- 0% {
- background-position: 200% 0;
- }
- 100% {
- background-position: -200% 0;
- }
- }
-
- @keyframes typewriter {
- from {
- width: 0;
- }
- to {
- width: 100%;
- }
- }
-`
-
-export const ListItemEditInput = ({ className, ...props }: ComponentPropsWithRef<'input'>) => {
- return (
-
- )
-}
-
-export const ListContainer = ({ children, className, ...props }: ComponentPropsWithoutRef<'div'>) => {
- return (
-
- {children}
-
- )
-}
-
-export const MenuButton = ({ children, className, ...props }: ComponentPropsWithoutRef<'div'>) => {
- return (
-
- {children}
-
- )
-}
-
-export const StatusIndicator = ({ variant }: { variant: 'pending' | 'fulfilled' }) => {
- const colors = useMemo(() => {
- switch (variant) {
- case 'pending':
- return {
- wave: 'bg-warning-400',
- back: 'bg-warning-500'
- }
- case 'fulfilled':
- return {
- wave: 'bg-success-400',
- back: 'bg-success-500'
- }
- }
- }, [variant])
- return (
-
-
-
-
- )
-}
diff --git a/src/renderer/src/pages/home/Tabs/index.tsx b/src/renderer/src/pages/home/Tabs/index.tsx
index 3b9e057d80..7d6a77b50c 100644
--- a/src/renderer/src/pages/home/Tabs/index.tsx
+++ b/src/renderer/src/pages/home/Tabs/index.tsx
@@ -1,4 +1,3 @@
-import { Alert, Skeleton } from '@heroui/react'
import AddAssistantPopup from '@renderer/components/Popups/AddAssistantPopup'
import { useActiveSession } from '@renderer/hooks/agents/useActiveSession'
import { useUpdateSession } from '@renderer/hooks/agents/useUpdateSession'
@@ -12,6 +11,7 @@ import { setActiveAgentId, setActiveTopicOrSessionAction } from '@renderer/store
import type { Assistant, Topic } from '@renderer/types'
import type { Tab } from '@renderer/types/chat'
import { classNames, getErrorMessage, uuid } from '@renderer/utils'
+import { Alert, Skeleton } from 'antd'
import type { FC } from 'react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
@@ -166,16 +166,17 @@ const HomeTabs: FC
= ({
)}
{tab === 'settings' && isTopicView && }
{tab === 'settings' && isSessionView && !sessionError && (
-
+
)}
{tab === 'settings' && isSessionView && sessionError && (
)}
diff --git a/src/renderer/src/pages/home/components/ChatNavbarContent.tsx b/src/renderer/src/pages/home/components/ChatNavbarContent.tsx
index 65b9cdee11..5f9d30bd6d 100644
--- a/src/renderer/src/pages/home/components/ChatNavbarContent.tsx
+++ b/src/renderer/src/pages/home/components/ChatNavbarContent.tsx
@@ -1,4 +1,3 @@
-import { BreadcrumbItem, Breadcrumbs, cn } from '@heroui/react'
import HorizontalScrollContainer from '@renderer/components/HorizontalScrollContainer'
import { useActiveAgent } from '@renderer/hooks/agents/useActiveAgent'
import { useActiveSession } from '@renderer/hooks/agents/useActiveSession'
@@ -7,15 +6,18 @@ import { useRuntime } from '@renderer/hooks/useRuntime'
import type { AgentEntity, AgentSessionEntity, ApiModel, Assistant } from '@renderer/types'
import { formatErrorMessageWithPrefix } from '@renderer/utils/error'
import { t } from 'i18next'
-import { Folder } from 'lucide-react'
+import { ChevronRight, Folder } from 'lucide-react'
import type { FC, ReactNode } from 'react'
import { useCallback } from 'react'
+import { twMerge } from 'tailwind-merge'
import { AgentSettingsPopup, SessionSettingsPopup } from '../../settings/AgentSettings'
import { AgentLabel, SessionLabel } from '../../settings/AgentSettings/shared'
import SelectAgentBaseModelButton from './SelectAgentBaseModelButton'
import SelectModelButton from './SelectModelButton'
+const cn = (...inputs: any[]) => twMerge(inputs)
+
interface Props {
assistant: Assistant
}
@@ -40,43 +42,53 @@ const ChatNavbarContent: FC = ({ assistant }) => {
{activeTopicOrSession === 'topic' && }
{activeTopicOrSession === 'session' && activeAgent && (
-
- AgentSettingsPopup.show({ agentId: activeAgent.id })}
- classNames={{ base: 'self-stretch', item: 'h-full' }}>
+
+ {/* Agent Label */}
+
AgentSettingsPopup.show({ agentId: activeAgent.id })}>
-
+
+
{activeSession && (
-
- SessionSettingsPopup.show({
- agentId: activeAgent.id,
- sessionId: activeSession.id
- })
- }
- classNames={{ base: 'self-stretch', item: 'h-full' }}>
-
-
- )}
- {activeSession && (
-
+ <>
+ {/* Separator */}
+
+
+ {/* Session Label */}
+
+ SessionSettingsPopup.show({
+ agentId: activeAgent.id,
+ sessionId: activeSession.id
+ })
+ }>
+
+
+
+ {/* Separator */}
+
+
+ {/* Model Button */}
{
await handleUpdateModel(model)
}}
/>
-
- )}
- {activeAgent && activeSession && (
-
+
+ {/* Separator */}
+
+
+ {/* Workspace Meta */}
-
+ >
)}
-
+
)}
>
diff --git a/src/renderer/src/pages/home/components/SelectAgentBaseModelButton.tsx b/src/renderer/src/pages/home/components/SelectAgentBaseModelButton.tsx
index 1d46335e1b..e82a67d6c3 100644
--- a/src/renderer/src/pages/home/components/SelectAgentBaseModelButton.tsx
+++ b/src/renderer/src/pages/home/components/SelectAgentBaseModelButton.tsx
@@ -1,28 +1,59 @@
-import { Button } from '@heroui/react'
import ModelAvatar from '@renderer/components/Avatar/ModelAvatar'
import { SelectApiModelPopup } from '@renderer/components/Popups/SelectModelPopup'
import { agentModelFilter } from '@renderer/config/models'
import { useApiModel } from '@renderer/hooks/agents/useModel'
import { getProviderNameById } from '@renderer/services/ProviderService'
import type { AgentBaseWithId, ApiModel } from '@renderer/types'
+import { isAgentSessionEntity } from '@renderer/types'
import { isAgentEntity } from '@renderer/types'
import { getModelFilterByAgentType } from '@renderer/utils/agentSession'
import { apiModelAdapter } from '@renderer/utils/model'
+import type { ButtonProps } from 'antd'
+import { Button } from 'antd'
import { ChevronsUpDown } from 'lucide-react'
-import type { FC } from 'react'
+import type { CSSProperties, FC } from 'react'
import { useTranslation } from 'react-i18next'
interface Props {
agentBase: AgentBaseWithId
onSelect: (model: ApiModel) => Promise
isDisabled?: boolean
+ /** Custom className for the button */
+ className?: string
+ /** Custom inline styles for the button (merged with default styles) */
+ buttonStyle?: CSSProperties
+ /** Custom button size */
+ buttonSize?: ButtonProps['size']
+ /** Custom avatar size */
+ avatarSize?: number
+ /** Custom font size */
+ fontSize?: number
+ /** Custom icon size */
+ iconSize?: number
+ /** Custom className for the inner container (e.g., for justify-between) */
+ containerClassName?: string
}
-const SelectAgentBaseModelButton: FC = ({ agentBase: agent, onSelect, isDisabled }) => {
+const SelectAgentBaseModelButton: FC = ({
+ agentBase: agent,
+ onSelect,
+ isDisabled,
+ className,
+ buttonStyle,
+ buttonSize = 'small',
+ avatarSize = 20,
+ fontSize = 12,
+ iconSize = 14,
+ containerClassName
+}) => {
const { t } = useTranslation()
const model = useApiModel({ id: agent?.model })
- const apiFilter = isAgentEntity(agent) ? getModelFilterByAgentType(agent.type) : undefined
+ const apiFilter = isAgentEntity(agent)
+ ? getModelFilterByAgentType(agent.type)
+ : isAgentSessionEntity(agent)
+ ? getModelFilterByAgentType(agent.agent_type)
+ : undefined
if (!agent) return null
@@ -35,20 +66,31 @@ const SelectAgentBaseModelButton: FC = ({ agentBase: agent, onSelect, isD
const providerName = model?.provider ? getProviderNameById(model.provider) : model?.provider_name
+ // Merge default styles with custom styles
+ const mergedStyle: CSSProperties = {
+ borderRadius: 20,
+ fontSize,
+ padding: 2,
+ ...buttonStyle
+ }
+
return (