refactor(agents): rename useModels to useApiModels and extract model label component

Extract ModelLabel component into standalone ApiModelLabel and rename useModels hook to useApiModels for better clarity. Update all references to use the new names. This improves code organization and maintainability.
This commit is contained in:
icarus 2025-09-22 00:04:15 +08:00
parent 828c22310d
commit 710592b053
8 changed files with 52 additions and 28 deletions

View File

@ -0,0 +1,19 @@
import { Avatar, cn } from '@heroui/react'
import { getModelLogo } from '@renderer/config/models'
import { ApiModel } from '@renderer/types'
import React from 'react'
export interface ModelLabelProps extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {
model?: ApiModel
}
export const ApiModelLabel: React.FC<ModelLabelProps> = ({ model, className, ...props }) => {
return (
<div className={cn('flex items-center gap-1', className)} {...props}>
<Avatar src={model ? getModelLogo(model.id) : undefined} className="h-4 w-4" />
<span>
{model?.name} | {model?.provider_name}
</span>
</div>
)
}

View File

@ -18,7 +18,7 @@ import { loggerService } from '@logger'
import ClaudeIcon from '@renderer/assets/images/models/claude.png'
import { getModelLogo } from '@renderer/config/models'
import { useAgents } from '@renderer/hooks/agents/useAgents'
import { useModels } from '@renderer/hooks/agents/useModels'
import { useApiModels } from '@renderer/hooks/agents/useModels'
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
import { AddAgentForm, AgentEntity, AgentType, BaseAgentForm, isAgentType, UpdateAgentForm } from '@renderer/types'
import { ChangeEvent, FormEvent, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
@ -82,7 +82,7 @@ export const AgentModal: React.FC<Props> = ({ agent, trigger, isOpen: _isOpen, o
const { addAgent } = useAgents()
const updateAgent = useUpdateAgent()
// hard-coded. We only support anthropic for now.
const { models } = useModels({ providerType: 'anthropic' })
const { models } = useApiModels({ providerType: 'anthropic' })
const isEditing = (agent?: AgentEntity) => agent !== undefined
const [form, setForm] = useState<BaseAgentForm>(() => buildAgentForm(agent))

View File

@ -18,7 +18,7 @@ import {
import { loggerService } from '@logger'
import { getModelLogo } from '@renderer/config/models'
import { useAgent } from '@renderer/hooks/agents/useAgent'
import { useModels } from '@renderer/hooks/agents/useModels'
import { useApiModels } from '@renderer/hooks/agents/useModels'
import { useSessions } from '@renderer/hooks/agents/useSessions'
import { AgentEntity, AgentSessionEntity, BaseSessionForm, CreateSessionForm, UpdateSessionForm } from '@renderer/types'
import { ChangeEvent, FormEvent, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
@ -80,7 +80,7 @@ export const SessionModal: React.FC<Props> = ({ agentId, session, trigger, isOpe
// const { setTimeoutTimer } = useTimer()
const { createSession, updateSession } = useSessions(agentId)
// Only support claude code for now
const { models } = useModels({ providerType: 'anthropic' })
const { models } = useApiModels({ providerType: 'anthropic' })
const { agent } = useAgent(agentId)
const isEditing = (session?: AgentSessionEntity) => session !== undefined

View File

@ -0,0 +1,10 @@
import { useApiModels } from './useModels'
export type UseModelProps = {
id: string
}
export const useApiModel = (id?: string) => {
const { models } = useApiModels()
return models.find((model) => model.id === id)
}

View File

@ -4,7 +4,7 @@ import useSWR from 'swr'
import { useAgentClient } from './useAgentClient'
export const useModels = (filter?: ApiModelsFilter) => {
export const useApiModels = (filter?: ApiModelsFilter) => {
const client = useAgentClient()
const path = client.getModelsPath(filter)
const fetcher = useCallback(() => {

View File

@ -1,8 +1,11 @@
import { ApiModelLabel } from '@renderer/components/ApiModelLabel'
import { NavbarHeader } from '@renderer/components/app/Navbar'
import { HStack } from '@renderer/components/Layout'
import SearchPopup from '@renderer/components/Popups/SearchPopup'
import { useAgent } from '@renderer/hooks/agents/useAgent'
import { useApiModel } from '@renderer/hooks/agents/useModel'
import { useAssistant } from '@renderer/hooks/useAssistant'
import { modelGenerating } from '@renderer/hooks/useRuntime'
import { modelGenerating, useRuntime } from '@renderer/hooks/useRuntime'
import { useSettings } from '@renderer/hooks/useSettings'
import { useShortcut } from '@renderer/hooks/useShortcuts'
import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore'
@ -35,6 +38,10 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveAssistant, activeTo
const { topicPosition, narrowMode } = useSettings()
const { showTopics, toggleShowTopics } = useShowTopics()
const dispatch = useAppDispatch()
const { chat } = useRuntime()
const { activeTopicOrSession, activeAgentId } = chat
const { agent } = useAgent(activeAgentId)
const agentModel = useApiModel(agent?.model)
useShortcut('toggle_show_assistants', toggleShowAssistants)
@ -94,7 +101,10 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveAssistant, activeTo
</motion.div>
)}
</AnimatePresence>
<SelectModelButton assistant={assistant} />
{activeTopicOrSession === 'topic' && <SelectModelButton assistant={assistant} />}
{/* TODO: Show a select model button for agent. */}
{/* FIXME: models endpoint doesn't return all models, so cannot found. */}
{activeTopicOrSession === 'session' && <ApiModelLabel model={agentModel} />}
</HStack>
<HStack alignItems="center" gap={8}>
<UpdateAppButton />

View File

@ -1,4 +1,5 @@
import { useModels } from '@renderer/hooks/agents/useModels'
import { ApiModelLabel } from '@renderer/components/ApiModelLabel'
import { useApiModels } from '@renderer/hooks/agents/useModels'
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
import { AgentEntity, UpdateAgentForm } from '@renderer/types'
import { Input, Select } from 'antd'
@ -6,7 +7,7 @@ import { DefaultOptionType } from 'antd/es/select'
import { FC, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { AgentLabel, ModelLabel, SettingsContainer, SettingsItem, SettingsTitle } from './shared'
import { AgentLabel, SettingsContainer, SettingsItem, SettingsTitle } from './shared'
interface AgentEssentialSettingsProps {
agent: AgentEntity | undefined | null
@ -16,7 +17,7 @@ interface AgentEssentialSettingsProps {
const AgentEssentialSettings: FC<AgentEssentialSettingsProps> = ({ agent, update }) => {
const { t } = useTranslation()
const [name, setName] = useState<string>((agent?.name ?? '').trim())
const { models } = useModels({ providerType: 'anthropic' })
const { models } = useApiModels({ providerType: 'anthropic' })
const agentModel = models.find((model) => model.id === agent?.model)
const [model, setModel] = useState<string | undefined>(agentModel?.id)
@ -29,7 +30,7 @@ const AgentEssentialSettings: FC<AgentEssentialSettingsProps> = ({ agent, update
const modelOptions = useMemo(() => {
return models.map((model) => ({
value: model.id,
label: <ModelLabel model={model} />
label: <ApiModelLabel model={model} />
})) satisfies DefaultOptionType[]
}, [models])

View File

@ -1,8 +1,7 @@
import { Avatar, AvatarProps, cn } from '@heroui/react'
import { getAgentAvatar } from '@renderer/config/agent'
import { getModelLogo } from '@renderer/config/models'
import { getAgentTypeLabel } from '@renderer/i18n/label'
import { AgentType, ApiModel } from '@renderer/types'
import { AgentType } from '@renderer/types'
import React from 'react'
import { SettingDivider } from '..'
@ -64,18 +63,3 @@ export const SettingsContainer: React.FC<React.ComponentPropsWithRef<'div'>> = (
</div>
)
}
export interface ModelLabelProps extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {
model: ApiModel
}
export const ModelLabel: React.FC<ModelLabelProps> = ({ model, className, ...props }) => {
return (
<div className={cn('flex items-center gap-1', className)} {...props}>
<Avatar src={getModelLogo(model.id)} className="h-4 w-4" />
<span>
{model.name} | {model.provider_name}
</span>
</div>
)
}