diff --git a/src/renderer/src/hooks/useAgents.ts b/src/renderer/src/hooks/useAgents.ts
new file mode 100644
index 00000000..25178d1b
--- /dev/null
+++ b/src/renderer/src/hooks/useAgents.ts
@@ -0,0 +1,31 @@
+import { useAppDispatch, useAppSelector } from '@renderer/store'
+import {
+ addAgent,
+ addConversationToAgent,
+ removeAgent,
+ removeConversationFromAgent,
+ updateAgent
+} from '@renderer/store/agents'
+import { Agent } from '@renderer/types'
+import { useState } from 'react'
+
+export default function useAgents() {
+ const { agents } = useAppSelector((state) => state.agents)
+ const [agentId, setAgentId] = useState(agents[0]?.id)
+ const dispatch = useAppDispatch()
+
+ return {
+ agents,
+ agent: agents.find((t) => t.id === agentId),
+ setAgent: (agent: Agent) => setAgentId(agent.id),
+ addAgent: (agent: Agent) => dispatch(addAgent(agent)),
+ removeAgent: (id: string) => dispatch(removeAgent({ id })),
+ updateAgent: (agent: Agent) => dispatch(updateAgent(agent)),
+ addConversation: (agentId: string, conversationId: string) => {
+ dispatch(addConversationToAgent({ agentId, conversationId }))
+ },
+ removeConversation: (agentId: string, conversationId: string) => {
+ dispatch(removeConversationFromAgent({ agentId, conversationId }))
+ }
+ }
+}
diff --git a/src/renderer/src/hooks/useThreads.ts b/src/renderer/src/hooks/useThreads.ts
deleted file mode 100644
index 34d55ecb..00000000
--- a/src/renderer/src/hooks/useThreads.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { useAppDispatch, useAppSelector } from '@renderer/store'
-import {
- addConversationToThread,
- addThread,
- removeConversationFromThread,
- removeThread,
- updateThread
-} from '@renderer/store/threads'
-import { Thread } from '@renderer/types'
-import { useState } from 'react'
-
-export default function useThreads() {
- const { threads } = useAppSelector((state) => state.threads)
- const [threadId, setThreadId] = useState(threads[0]?.id)
- const dispatch = useAppDispatch()
-
- return {
- threads,
- thread: threads.find((t) => t.id === threadId),
- setThread: (thread: Thread) => setThreadId(thread.id),
- addThread: (thread: Thread) => dispatch(addThread(thread)),
- removeThread: (id: string) => dispatch(removeThread({ id })),
- updateThread: (thread: Thread) => dispatch(updateThread(thread)),
- addConversation: (threadId: string, conversationId: string) => {
- dispatch(addConversationToThread({ threadId, conversationId }))
- },
- removeConversation: (threadId: string, conversationId: string) => {
- dispatch(removeConversationFromThread({ threadId, conversationId }))
- }
- }
-}
diff --git a/src/renderer/src/pages/home/HomePage.tsx b/src/renderer/src/pages/home/HomePage.tsx
index 6b507909..6a67052e 100644
--- a/src/renderer/src/pages/home/HomePage.tsx
+++ b/src/renderer/src/pages/home/HomePage.tsx
@@ -1,20 +1,20 @@
import { Navbar, NavbarCenter, NavbarLeft, NavbarRight } from '@renderer/components/app/Navbar'
-import useThreads from '@renderer/hooks/useThreads'
+import useAgents from '@renderer/hooks/useAgents'
import { FC, useEffect } from 'react'
import styled from 'styled-components'
import Chat from './components/Chat'
-import Threads from './components/Threads'
+import Agents from './components/Agents'
import { uuid } from '@renderer/utils'
const HomePage: FC = () => {
- const { threads, thread, setThread, addThread } = useThreads()
+ const { agents, agent, setAgent, addAgent } = useAgents()
useEffect(() => {
- !thread && threads[0] && setThread(threads[0])
- }, [thread, threads])
+ !agent && agents[0] && setAgent(agents[0])
+ }, [agent, agents])
const onCreateConversation = () => {
- const _thread = {
+ const _agent = {
id: uuid(),
name: 'New conversation',
avatar: 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y',
@@ -22,8 +22,8 @@ const HomePage: FC = () => {
lastMessageAt: 'now',
conversations: []
}
- addThread(_thread)
- setThread(_thread)
+ addAgent(_agent)
+ setAgent(_agent)
}
return (
@@ -34,7 +34,7 @@ const HomePage: FC = () => {
- {thread?.name}
+ {agent?.name}
@@ -42,8 +42,8 @@ const HomePage: FC = () => {
-
- {thread && }
+
+ {agent && }
)
diff --git a/src/renderer/src/pages/home/components/Threads.tsx b/src/renderer/src/pages/home/components/Agents.tsx
similarity index 66%
rename from src/renderer/src/pages/home/components/Threads.tsx
rename to src/renderer/src/pages/home/components/Agents.tsx
index 1ae95ef0..99d0ad4f 100644
--- a/src/renderer/src/pages/home/components/Threads.tsx
+++ b/src/renderer/src/pages/home/components/Agents.tsx
@@ -2,32 +2,29 @@ import { FC } from 'react'
import styled from 'styled-components'
import { IconMore } from '@douyinfe/semi-icons'
import { Dropdown } from '@douyinfe/semi-ui'
-import useThreads from '@renderer/hooks/useThreads'
+import useAgents from '@renderer/hooks/useAgents'
-const Threads: FC = () => {
- const { threads, thread, setThread, removeThread } = useThreads()
+const Agents: FC = () => {
+ const { agents, setAgent, removeAgent } = useAgents()
return (
- {threads.map((thread) => (
- setThread(thread)}
- className={thread.id === thread?.id ? 'active' : ''}>
+ {agents.map((agent) => (
+ setAgent(agent)} className={agent.id === agent?.id ? 'active' : ''}>
- removeThread(thread.id)}>Delete
+ removeAgent(agent.id)}>Delete
}>
- {thread.name}
- {thread.lastMessage}
- {thread.lastMessageAt}
-
+ {agent.name}
+ {agent.lastMessage}
+ {agent.lastMessageAt}
+
))}
)
@@ -47,7 +44,7 @@ const Container = styled.div`
}
`
-const ThreadItem = styled.div`
+const AgentItem = styled.div`
display: flex;
flex-direction: column;
padding: 10px;
@@ -70,18 +67,18 @@ const ThreadItem = styled.div`
margin-bottom: 10px;
`
-const ThreadTime = styled.div`
+const AgentTime = styled.div`
font-size: 12px;
color: var(--color-text-2);
`
-const ThreadName = styled.div`
+const AgentName = styled.div`
font-size: 14px;
color: var(--color-text-1);
font-weight: bold;
`
-const ThreadLastMessage = styled.div`
+const AgentLastMessage = styled.div`
font-size: 12px;
line-height: 20px;
color: var(--color-text-2);
@@ -93,4 +90,4 @@ const ThreadLastMessage = styled.div`
height: 20px;
`
-export default Threads
+export default Agents
diff --git a/src/renderer/src/pages/home/components/Chat.tsx b/src/renderer/src/pages/home/components/Chat.tsx
index feb1db44..d9b3c126 100644
--- a/src/renderer/src/pages/home/components/Chat.tsx
+++ b/src/renderer/src/pages/home/components/Chat.tsx
@@ -1,24 +1,24 @@
-import { Message, Thread } from '@renderer/types'
+import { Message, Agent } from '@renderer/types'
import { FC, useState } from 'react'
import styled from 'styled-components'
import Inputbar from './Inputbar'
import Conversations from './Conversations'
-import useThreads from '@renderer/hooks/useThreads'
+import useAgents from '@renderer/hooks/useAgents'
import { isEmpty } from 'lodash'
import localforage from 'localforage'
import { uuid } from '@renderer/utils'
interface Props {
- thread: Thread
+ agent: Agent
}
-const Chat: FC = ({ thread }) => {
- const [conversationId] = useState(thread.conversations[0] || uuid())
+const Chat: FC = ({ agent }) => {
+ const [conversationId] = useState(agent.conversations[0] || uuid())
return (
-
-
+
+
)
}
diff --git a/src/renderer/src/pages/home/components/Conversations.tsx b/src/renderer/src/pages/home/components/Conversations.tsx
index 0fd9966d..fe33eb23 100644
--- a/src/renderer/src/pages/home/components/Conversations.tsx
+++ b/src/renderer/src/pages/home/components/Conversations.tsx
@@ -1,7 +1,7 @@
import { Avatar } from '@douyinfe/semi-ui'
-import useThreads from '@renderer/hooks/useThreads'
+import useAgents from '@renderer/hooks/useAgents'
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
-import { Conversation, Message, Thread } from '@renderer/types'
+import { Conversation, Message, Agent } from '@renderer/types'
import { runAsyncFunction } from '@renderer/utils'
import localforage from 'localforage'
import { isEmpty } from 'lodash'
@@ -9,19 +9,19 @@ import { FC, useEffect, useState } from 'react'
import styled from 'styled-components'
interface Props {
- thread: Thread
+ agent: Agent
conversationId: string
}
-const Conversations: FC = ({ thread, conversationId }) => {
+const Conversations: FC = ({ agent, conversationId }) => {
const [messages, setMessages] = useState([])
- const { addConversation } = useThreads()
+ const { addConversation } = useAgents()
const onSendMessage = (message: Message) => {
setMessages([...messages, message])
- if (isEmpty(thread?.conversations)) {
- addConversation(thread.id, conversationId)
+ if (isEmpty(agent?.conversations)) {
+ addConversation(agent.id, conversationId)
}
localforage.setItem(`conversation:${conversationId}`, {
diff --git a/src/renderer/src/pages/home/components/Inputbar.tsx b/src/renderer/src/pages/home/components/Inputbar.tsx
index d8ce4c7b..b23cb45d 100644
--- a/src/renderer/src/pages/home/components/Inputbar.tsx
+++ b/src/renderer/src/pages/home/components/Inputbar.tsx
@@ -1,24 +1,24 @@
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
-import { Message, Thread } from '@renderer/types'
+import { Message, Agent } from '@renderer/types'
import { uuid } from '@renderer/utils'
import { FC, useState } from 'react'
import styled from 'styled-components'
interface Props {
- thread: Thread
+ agent: Agent
}
-const Inputbar: FC = ({ thread }) => {
+const Inputbar: FC = ({ agent }) => {
const [text, setText] = useState('')
const handleKeyDown = (event: React.KeyboardEvent) => {
if (event.key === 'Enter') {
- const conversationId = thread.conversations[0] ? thread.conversations[0] : uuid()
+ const conversationId = agent.conversations[0] ? agent.conversations[0] : uuid()
const message: Message = {
id: uuid(),
content: text,
- threadId: thread.id,
+ agentId: agent.id,
conversationId,
createdAt: 'now'
}
diff --git a/src/renderer/src/services/thread.ts b/src/renderer/src/services/agent.ts
similarity index 85%
rename from src/renderer/src/services/thread.ts
rename to src/renderer/src/services/agent.ts
index d9db411f..78725c25 100644
--- a/src/renderer/src/services/thread.ts
+++ b/src/renderer/src/services/agent.ts
@@ -1,4 +1,4 @@
-export function getDefaultThread() {
+export function getDefaultAgent() {
return {
id: 'default',
name: 'Chat Assistant',
diff --git a/src/renderer/src/store/agents.ts b/src/renderer/src/store/agents.ts
new file mode 100644
index 00000000..555ff218
--- /dev/null
+++ b/src/renderer/src/store/agents.ts
@@ -0,0 +1,52 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit'
+import { getDefaultAgent } from '@renderer/services/agent'
+import { Agent } from '@renderer/types'
+
+export interface AgentsState {
+ agents: Agent[]
+}
+
+const initialState: AgentsState = {
+ agents: [getDefaultAgent()]
+}
+
+const agentsSlice = createSlice({
+ name: 'agents',
+ initialState,
+ reducers: {
+ addAgent: (state, action: PayloadAction) => {
+ state.agents.push(action.payload)
+ },
+ removeAgent: (state, action: PayloadAction<{ id: string }>) => {
+ state.agents = state.agents.filter((c) => c.id !== action.payload.id)
+ },
+ updateAgent: (state, action: PayloadAction) => {
+ state.agents = state.agents.map((c) => (c.id === action.payload.id ? action.payload : c))
+ },
+ addConversationToAgent: (state, action: PayloadAction<{ agentId: string; conversationId: string }>) => {
+ state.agents = state.agents.map((c) =>
+ c.id === action.payload.agentId
+ ? {
+ ...c,
+ conversations: [...c.conversations, action.payload.conversationId]
+ }
+ : c
+ )
+ },
+ removeConversationFromAgent: (state, action: PayloadAction<{ agentId: string; conversationId: string }>) => {
+ state.agents = state.agents.map((c) =>
+ c.id === action.payload.agentId
+ ? {
+ ...c,
+ conversations: c.conversations.filter((id) => id !== action.payload.conversationId)
+ }
+ : c
+ )
+ }
+ }
+})
+
+export const { addAgent, removeAgent, updateAgent, addConversationToAgent, removeConversationFromAgent } =
+ agentsSlice.actions
+
+export default agentsSlice.reducer
diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts
index e5674f6f..04ca1d4f 100644
--- a/src/renderer/src/store/index.ts
+++ b/src/renderer/src/store/index.ts
@@ -2,7 +2,7 @@ import { combineReducers, configureStore } from '@reduxjs/toolkit'
import { useDispatch, useSelector, useStore } from 'react-redux'
import { FLUSH, PAUSE, PERSIST, persistReducer, persistStore, PURGE, REGISTER, REHYDRATE } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
-import threads from './threads'
+import agents from './agents'
const store = configureStore({
reducer: persistReducer(
@@ -12,7 +12,7 @@ const store = configureStore({
version: 1
},
combineReducers({
- threads
+ agents
})
),
middleware: (getDefaultMiddleware) => {
diff --git a/src/renderer/src/store/threads.ts b/src/renderer/src/store/threads.ts
deleted file mode 100644
index f84652b7..00000000
--- a/src/renderer/src/store/threads.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { createSlice, PayloadAction } from '@reduxjs/toolkit'
-import { getDefaultThread } from '@renderer/services/thread'
-import { Thread } from '@renderer/types'
-
-export interface ThreadsState {
- threads: Thread[]
-}
-
-const initialState: ThreadsState = {
- threads: [getDefaultThread()]
-}
-
-const threadsSlice = createSlice({
- name: 'threads',
- initialState,
- reducers: {
- addThread: (state, action: PayloadAction) => {
- state.threads.push(action.payload)
- },
- removeThread: (state, action: PayloadAction<{ id: string }>) => {
- state.threads = state.threads.filter((c) => c.id !== action.payload.id)
- },
- updateThread: (state, action: PayloadAction) => {
- state.threads = state.threads.map((c) => (c.id === action.payload.id ? action.payload : c))
- },
- addConversationToThread: (state, action: PayloadAction<{ threadId: string; conversationId: string }>) => {
- state.threads = state.threads.map((c) =>
- c.id === action.payload.threadId
- ? {
- ...c,
- conversations: [...c.conversations, action.payload.conversationId]
- }
- : c
- )
- },
- removeConversationFromThread: (state, action: PayloadAction<{ threadId: string; conversationId: string }>) => {
- state.threads = state.threads.map((c) =>
- c.id === action.payload.threadId
- ? {
- ...c,
- conversations: c.conversations.filter((id) => id !== action.payload.conversationId)
- }
- : c
- )
- }
- }
-})
-
-export const { addThread, removeThread, updateThread, addConversationToThread, removeConversationFromThread } =
- threadsSlice.actions
-
-export default threadsSlice.reducer
diff --git a/src/renderer/src/types/index.ts b/src/renderer/src/types/index.ts
index 2062aa41..ad98994e 100644
--- a/src/renderer/src/types/index.ts
+++ b/src/renderer/src/types/index.ts
@@ -1,4 +1,4 @@
-export type Thread = {
+export type Agent = {
id: string
name: string
avatar: string
@@ -10,7 +10,7 @@ export type Thread = {
export type Message = {
id: string
content: string
- threadId: string
+ agentId: string
conversationId: string
createdAt: string
}