refactor(sessions): extract sessions component and update hook to use agentId

Move sessions rendering logic to a separate component and modify useSessions hook to work with agentId instead of full agent entity. This improves code organization and simplifies the hook interface.
This commit is contained in:
icarus 2025-09-19 14:07:23 +08:00
parent 14509d1077
commit 3d561ad8e3
3 changed files with 57 additions and 33 deletions

View File

@ -1,64 +1,72 @@
import { AgentEntity, CreateSessionForm, UpdateSessionForm } from '@renderer/types' import { CreateSessionForm, UpdateSessionForm } from '@renderer/types'
import { useCallback } from 'react' import { useCallback } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import useSWR from 'swr' import useSWR from 'swr'
import { useAgentClient } from './useAgentClient' import { useAgentClient } from './useAgentClient'
export const useSessions = (agent: AgentEntity) => { export const useSessions = (agentId: string) => {
const { t } = useTranslation() const { t } = useTranslation()
const client = useAgentClient() const client = useAgentClient()
const key = client.agentPaths.base const key = client.getSessionPaths(agentId).base
const fetcher = async () => { const fetcher = async () => {
const data = await client.listSessions(agent.id) if (!agentId) {
return []
}
const data = await client.listSessions(agentId)
return data.data return data.data
} }
const { data, error, isLoading, mutate } = useSWR(key, fetcher) const { data, error, isLoading, mutate } = useSWR(key, fetcher)
const createSession = useCallback( const createSession = useCallback(
async (form: CreateSessionForm) => { async (form: CreateSessionForm) => {
if (!agentId) return
try { try {
const result = await client.createSession(agent.id, form) const result = await client.createSession(agentId, form)
mutate((prev) => [...(prev ?? []), result]) mutate((prev) => [...(prev ?? []), result])
} catch (error) { } catch (error) {
window.toast.error(t('agent.session.create.error.failed')) window.toast.error(t('agent.session.create.error.failed'))
} }
}, },
[agent.id, client, mutate, t] [agentId, client, mutate, t]
) )
// TODO: including messages field // TODO: including messages field
const getSession = useCallback( const getSession = useCallback(
async (id: string) => { async (id: string) => {
const result = await client.getSession(agent.id, id) if (!agentId) return
const result = await client.getSession(agentId, id)
mutate((prev) => prev?.map((session) => (session.id === result.id ? result : session))) mutate((prev) => prev?.map((session) => (session.id === result.id ? result : session)))
return result return result
}, },
[agent.id, client, mutate] [agentId, client, mutate]
) )
const deleteSession = useCallback( const deleteSession = useCallback(
async (id: string) => { async (id: string) => {
if (!agentId) return
try { try {
await client.deleteSession(agent.id, id) await client.deleteSession(agentId, id)
mutate((prev) => prev?.filter((session) => session.id !== id)) mutate((prev) => prev?.filter((session) => session.id !== id))
} catch (error) { } catch (error) {
window.toast.error(t('agent.session.delete.error.failed')) window.toast.error(t('agent.session.delete.error.failed'))
} }
}, },
[agent.id, client, mutate, t] [agentId, client, mutate, t]
) )
const updateSession = useCallback( const updateSession = useCallback(
async (id: string, form: UpdateSessionForm) => { async (id: string, form: UpdateSessionForm) => {
if (!agentId) return
try { try {
const result = await client.updateSession(agent.id, id, form) const result = await client.updateSession(agentId, id, form)
mutate((prev) => prev?.map((session) => (session.id === id ? result : session))) mutate((prev) => prev?.map((session) => (session.id === id ? result : session)))
} catch (error) { } catch (error) {
window.toast.error(t('agent.session.update.error.failed')) window.toast.error(t('agent.session.update.error.failed'))
} }
}, },
[agent.id, client, mutate, t] [agentId, client, mutate, t]
) )
return { return {

View File

@ -1,32 +1,22 @@
import { useRuntime } from '@renderer/hooks/useRuntime' import { useRuntime } from '@renderer/hooks/useRuntime'
import { AgentSessionEntity } from '@renderer/types'
import { FC, memo } from 'react' import { FC, memo } from 'react'
interface AssistantsTabProps {} import Sessions from './components/Sessions'
const SessionsTab: FC<AssistantsTabProps> = () => { interface SessionsTabProps {}
const SessionsTab: FC<SessionsTabProps> = () => {
const { chat } = useRuntime() const { chat } = useRuntime()
const { activeAgentId } = chat const { activeAgentId } = chat
const mockData: AgentSessionEntity[] = [
{ if (!activeAgentId) {
accessible_paths: [], return <div> No active agent.</div>
model: '', }
id: 'test',
agent_id: '',
agent_type: 'claude-code',
created_at: '',
updated_at: ''
}
]
return ( return (
<div className="agents-tab h-full w-full p-2"> <>
{/* TODO: Add session button */} <Sessions agentId={activeAgentId} />
Active Agent ID: {activeAgentId} </>
{mockData.map((session) => (
<div key={session.id}>Not implemented</div>
))}
</div>
) )
} }

View File

@ -0,0 +1,26 @@
import { loggerService } from '@logger'
import { useSessions } from '@renderer/hooks/agents/useSessions'
import { memo } from 'react'
const logger = loggerService.withContext('SessionsTab')
interface SessionsProps {
agentId: string
}
const Sessions: React.FC<SessionsProps> = ({ agentId }) => {
const { sessions } = useSessions(agentId)
logger.debug('Sessions', sessions)
return (
<div className="agents-tab h-full w-full p-2">
{/* TODO: Add session button */}
Active Agent ID: {agentId}
{sessions.map((session) => (
<div key={session.id}>Not implemented</div>
))}
</div>
)
}
export default memo(Sessions)