Skip to content

Commit

Permalink
Merge pull request #402 from BobDu/room-chat-model
Browse files Browse the repository at this point in the history
feat: set user deafult model & set chat model by per chat room
  • Loading branch information
Kerwin1202 authored Jan 8, 2024
2 parents ddb64df + adcbf4b commit f4c3d0c
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 35 deletions.
8 changes: 3 additions & 5 deletions service/src/chatgpt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { getCacheApiKeys, getCacheConfig, getOriginConfig } from '../storage/con
import { sendResponse } from '../utils'
import { hasAnyRole, isNotEmptyString } from '../utils/is'
import type { ChatContext, ChatGPTUnofficialProxyAPIOptions, JWT, ModelConfig } from '../types'
import { getChatByMessageId, updateRoomAccountId, updateRoomChatModel } from '../storage/mongo'
import { getChatByMessageId, updateRoomAccountId } from '../storage/mongo'
import type { RequestOptions } from './types'

const { HttpsProxyAgent } = httpsProxyAgent
Expand Down Expand Up @@ -113,8 +113,8 @@ export async function initApi(key: KeyConfig, chatModel: string, maxContextCount
}
const processThreads: { userId: string; abort: AbortController; messageId: string }[] = []
async function chatReplyProcess(options: RequestOptions) {
const model = options.user.config.chatModel
const key = await getRandomApiKey(options.user, options.user.config.chatModel, options.room.accountId)
const model = options.room.chatModel
const key = await getRandomApiKey(options.user, model, options.room.accountId)
const userId = options.user._id.toString()
const maxContextCount = options.user.advanced.maxContextCount ?? 20
const messageId = options.messageId
Expand All @@ -130,8 +130,6 @@ async function chatReplyProcess(options: RequestOptions) {
throw new Error('无法在一个房间同时使用 AccessToken 以及 Api,请联系管理员,或新开聊天室进行对话 | Unable to use AccessToken and Api at the same time in the same room, please contact the administrator or open a new chat room for conversation')
}

updateRoomChatModel(userId, options.room.roomId, model)

const { message, lastContext, process, systemMessage, temperature, top_p } = options

try {
Expand Down
4 changes: 2 additions & 2 deletions service/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ router.get('/chatrooms', auth, async (req, res) => {
router.post('/room-create', auth, async (req, res) => {
try {
const userId = req.headers.userId as string
const { title, roomId } = req.body as { title: string; roomId: number }
const room = await createChatRoom(userId, title, roomId)
const { title, roomId, chatModel } = req.body as { title: string; roomId: number; chatModel: string }
const room = await createChatRoom(userId, title, roomId, chatModel)
res.send({ status: 'Success', message: null, data: room })
}
catch (error) {
Expand Down
4 changes: 2 additions & 2 deletions service/src/storage/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ export class ChatRoom {
// only access token used
accountId?: string
chatModel: string
constructor(userId: string, title: string, roomId: number) {
constructor(userId: string, title: string, roomId: number, chatModel: string) {
this.userId = userId
this.title = title
this.prompt = undefined
this.roomId = roomId
this.usingContext = true
this.accountId = null
this.chatModel = null
this.chatModel = chatModel
}
}

Expand Down
4 changes: 2 additions & 2 deletions service/src/storage/mongo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ export async function insertChatUsage(userId: ObjectId, roomId: number, chatId:
return chatUsage
}

export async function createChatRoom(userId: string, title: string, roomId: number) {
const room = new ChatRoom(userId, title, roomId)
export async function createChatRoom(userId: string, title: string, roomId: number, chatModel: string) {
const room = new ChatRoom(userId, title, roomId, chatModel)
await roomCol.insertOne(room)
return room
}
Expand Down
11 changes: 9 additions & 2 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,10 @@ export function fetchGetChatRooms<T = any>() {
})
}

export function fetchCreateChatRoom<T = any>(title: string, roomId: number) {
export function fetchCreateChatRoom<T = any>(title: string, roomId: number, chatModel?: string) {
return post<T>({
url: '/room-create',
data: { title, roomId },
data: { title, roomId, chatModel },
})
}

Expand All @@ -206,6 +206,13 @@ export function fetchUpdateChatRoomPrompt<T = any>(prompt: string, roomId: numbe
})
}

export function fetchUpdateChatRoomChatModel<T = any>(chatModel: string, roomId: number) {
return post<T>({
url: '/room-chatmodel',
data: { chatModel, roomId },
})
}

export function fetchUpdateChatRoomUsingContext<T = any>(using: boolean, roomId: number) {
return post<T>({
url: '/room-context',
Expand Down
41 changes: 32 additions & 9 deletions src/components/common/Setting/General.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { NButton, NInput, NPopconfirm, NSelect, useMessage } from 'naive-ui'
import { NButton, NDivider, NInput, NPopconfirm, NSelect, useMessage } from 'naive-ui'
import { UserConfig } from '@/components/common/Setting/model'
import type { Language, Theme } from '@/store/modules/app/helper'
import { SvgIcon } from '@/components/common'
import { useAppStore, useUserStore } from '@/store'
import { useAppStore, useAuthStore, useUserStore } from '@/store'
import type { UserInfo } from '@/store/modules/user/helper'
import { getCurrentDate } from '@/utils/functions'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { t } from '@/locales'
import { fetchClearAllChat } from '@/api'
import { fetchClearAllChat, fetchUpdateUserChatModel } from '@/api'
const appStore = useAppStore()
const userStore = useUserStore()
const authStore = useAuthStore()
const { isMobile } = useBasicLayout()
Expand Down Expand Up @@ -66,6 +68,14 @@ async function updateUserInfo(options: Partial<UserInfo>) {
ms.success(t('common.success'))
}
async function updateUserChatModel(chatModel: string) {
if (!userStore.userInfo.config)
userStore.userInfo.config = new UserConfig()
userStore.userInfo.config.chatModel = chatModel
userStore.recordState()
await fetchUpdateUserChatModel(chatModel)
}
function exportData(): void {
const date = getCurrentDate()
const data: string = localStorage.getItem('chatStorage') || '{}'
Expand Down Expand Up @@ -138,6 +148,25 @@ function handleImportButtonClick(): void {
<NInput v-model:value="avatar" placeholder="" />
</div>
</div>
<div class="flex items-center space-x-4">
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.saveUserInfo') }}</span>
<NButton type="primary" @click="updateUserInfo({ avatar, name, description })">
{{ $t('common.save') }}
</NButton>
</div>
<NDivider />
<div class="flex items-center space-x-4">
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.defaultChatModel') }}</span>
<div class="w-[200px]">
<NSelect
style="width: 200px"
:value="userInfo.config.chatModel"
:options="authStore.session?.chatModels"
:disabled="!!authStore.session?.auth && !authStore.token"
@update-value="(val) => updateUserChatModel(val)"
/>
</div>
</div>
<div
class="flex items-center space-x-4"
:class="isMobile && 'items-start'"
Expand Down Expand Up @@ -200,12 +229,6 @@ function handleImportButtonClick(): void {
/>
</div>
</div>
<div class="flex items-center space-x-4">
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.saveUserInfo') }}</span>
<NButton type="primary" @click="updateUserInfo({ avatar, name, description })">
{{ $t('common.save') }}
</NButton>
</div>
</div>
</div>
</template>
1 change: 1 addition & 0 deletions src/locales/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export default {
userRoles: 'User Role',
status: 'Status',
chatModels: 'Chat Models',
defaultChatModel: 'Default Chat Model',
remark: 'Remark',
email: 'Email',
password: 'Password',
Expand Down
1 change: 1 addition & 0 deletions src/locales/ko-KR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export default {
userRoles: 'User Role',
status: 'Status',
chatModels: 'Chat Models',
defaultChatModel: '기본 대화 모델',
remark: 'Remark',
email: 'Email',
password: 'Password',
Expand Down
1 change: 1 addition & 0 deletions src/locales/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export default {
userRoles: '用户权限',
status: '状态',
chatModels: '对话模型',
defaultChatModel: '默认对话模型',
remark: '备注',
email: '电子邮箱',
password: '密码',
Expand Down
1 change: 1 addition & 0 deletions src/locales/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export default {
userRoles: '用戶權限',
status: '狀態',
chatModels: '對話模型',
defaultChatModel: '預設對話模型',
remark: '備註',
email: '電子郵箱',
password: '密碼',
Expand Down
40 changes: 35 additions & 5 deletions src/store/modules/chat/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
import { defineStore } from 'pinia'
import { getLocalState, setLocalState } from './helper'
import { useUserStore } from '@/store'
import { router } from '@/router'
import { fetchClearChat, fetchCreateChatRoom, fetchDeleteChat, fetchDeleteChatRoom, fetchGetChatHistory, fetchGetChatRooms, fetchRenameChatRoom, fetchUpdateChatRoomUsingContext } from '@/api'
import {
fetchClearChat,
fetchCreateChatRoom,
fetchDeleteChat,
fetchDeleteChatRoom,
fetchGetChatHistory,
fetchGetChatRooms,
fetchRenameChatRoom,
fetchUpdateChatRoomChatModel,
fetchUpdateChatRoomUsingContext,
fetchUpdateUserChatModel,
} from '@/api'

export const useChatStore = defineStore('chat-store', {
state: (): Chat.ChatState => getLocalState(),
Expand Down Expand Up @@ -39,7 +51,7 @@ export const useChatStore = defineStore('chat-store', {
this.chat.unshift({ uuid: r.uuid, data: [] })
}
if (uuid == null) {
await this.addHistory({ title: 'New Chat', uuid: Date.now(), isEdit: false, usingContext: true })
await this.addNewHistory()
}
else {
this.active = uuid
Expand Down Expand Up @@ -94,12 +106,30 @@ export const useChatStore = defineStore('chat-store', {
this.recordState()
},

async setChatModel(chatModel: string, roomId: number) {
await fetchUpdateChatRoomChatModel(chatModel, roomId)
const userStore = useUserStore()
userStore.userInfo.config.chatModel = chatModel
await fetchUpdateUserChatModel(chatModel)
},

async addHistory(history: Chat.History, chatData: Chat.Chat[] = []) {
await fetchCreateChatRoom(history.title, history.uuid)
await fetchCreateChatRoom(history.title, history.uuid, history.chatModel)
this.history.unshift(history)
this.chat.unshift({ uuid: history.uuid, data: chatData })
this.active = history.uuid
this.reloadRoute(history.uuid)
await this.reloadRoute(history.uuid)
},

async addNewHistory() {
const userStore = useUserStore()
await this.addHistory({
title: 'New Chat',
uuid: Date.now(),
isEdit: false,
usingContext: true,
chatModel: userStore.userInfo.config.chatModel,
})
},

updateHistory(uuid: number, edit: Partial<Chat.History>) {
Expand All @@ -118,7 +148,7 @@ export const useChatStore = defineStore('chat-store', {
this.chat.splice(index, 1)

if (this.history.length === 0) {
await this.addHistory({ title: 'New Chat', uuid: Date.now(), isEdit: false, usingContext: true })
await this.addNewHistory()
return
}

Expand Down
13 changes: 6 additions & 7 deletions src/views/chat/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import HeaderComponent from './components/Header/index.vue'
import { HoverButton, SvgIcon } from '@/components/common'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { useAuthStore, useChatStore, usePromptStore, useUserStore } from '@/store'
import { fetchChatAPIProcess, fetchChatResponseoHistory, fetchChatStopResponding, fetchUpdateUserChatModel } from '@/api'
import {
fetchChatAPIProcess,
fetchChatResponseoHistory,
fetchChatStopResponding,
} from '@/api'
import { t } from '@/locales'
import { debounce } from '@/utils/functions/debounce'
import IconPrompt from '@/icons/Prompt.vue'
import { UserConfig } from '@/components/common/Setting/model'
const Prompt = defineAsyncComponent(() => import('@/components/common/Setting/Prompt.vue'))
let controller = new AbortController()
Expand Down Expand Up @@ -582,11 +585,7 @@ const footerClass = computed(() => {
async function handleSyncChatModel(chatModel: string) {
nowSelectChatModel.value = chatModel
if (userStore.userInfo.config == null)
userStore.userInfo.config = new UserConfig()
userStore.userInfo.config.chatModel = chatModel
userStore.recordState()
await fetchUpdateUserChatModel(chatModel)
await chatStore.setChatModel(chatModel, +uuid)
}
onMounted(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/views/chat/layout/sider/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const show = ref(false)
const collapsed = computed(() => appStore.siderCollapsed)
async function handleAdd() {
await chatStore.addHistory({ title: 'New Chat', uuid: Date.now(), isEdit: false, usingContext: true })
await chatStore.addNewHistory()
if (isMobile.value)
appStore.setSiderCollapsed(true)
}
Expand Down

0 comments on commit f4c3d0c

Please sign in to comment.