Skip to content

Commit 14c323c

Browse files
author
Kerwin
committed
feat: support room specific prompt
fix: mobile login modal (Closes #41)
1 parent 807d400 commit 14c323c

File tree

16 files changed

+197
-19
lines changed

16 files changed

+197
-19
lines changed

README.en.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,18 @@
77
</br>
88

99
## Introduction
10-
> **This project is forked from [Chanzhaoyu/chatgpt-web](https://github.com/Chanzhaoyu/chatgpt-web). In addition to regularly merging this branch, some unique features have been added such as registration and login, setting API key on the front-end page.**
10+
> **This project is forked from [Chanzhaoyu/chatgpt-web](https://github.com/Chanzhaoyu/chatgpt-web), some unique features have been added:**
11+
12+
[] Register & Login & Reset Password
13+
14+
[] Sync chat history
15+
16+
[] Front-end page setting apikey
17+
18+
[] Custom Sensitive Words
19+
20+
[] Set unique prompts for each chat room
21+
1122
</br>
1223

1324
## Screenshots
@@ -17,6 +28,7 @@
1728
![cover](./docs/c1.png)
1829
![cover2](./docs/c2.png)
1930
![cover3](./docs/basesettings.jpg)
31+
![cover3](./docs/prompt_en.jpg)
2032

2133
- [ChatGPT Web](#chatgpt-web)
2234
- [Introduction](#introduction)

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@
77
</br>
88

99
## 说明
10-
> **此项目 Fork 自 [Chanzhaoyu/chatgpt-web](https://github.com/Chanzhaoyu/chatgpt-web), 除了定时合并该分支, 新增了部分特色功能, 注册&登录, 前端页面设置apikey 等**
10+
> **此项目 Fork 自 [Chanzhaoyu/chatgpt-web](https://github.com/Chanzhaoyu/chatgpt-web), 新增了部分特色功能:**
11+
12+
[] 注册&登录&重置密码
13+
14+
[] 同步历史会话
15+
16+
[] 前端页面设置apikey
17+
18+
[] 自定义敏感词
19+
20+
[] 每个会话设置独有 Prompt
1121
</br>
1222

1323
## 截图
@@ -17,6 +27,7 @@
1727
![cover](./docs/c1.png)
1828
![cover2](./docs/c2.png)
1929
![cover3](./docs/basesettings.jpg)
30+
![cover3](./docs/prompt.jpg)
2031

2132
- [ChatGPT Web](#chatgpt-web)
2233
- [介绍](#介绍)

docs/prompt.jpg

154 KB
Loading

docs/prompt_en.jpg

170 KB
Loading

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "chatgpt-web",
3-
"version": "2.12.0",
3+
"version": "2.12.3",
44
"private": false,
55
"description": "ChatGPT Web",
66
"author": "ChenZhaoYu <chenzhaoyu1994@gmail.com>",

service/src/index.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
deleteChatRoom,
1818
existsChatRoom,
1919
getChat,
20+
getChatRoom,
2021
getChatRooms,
2122
getChats,
2223
getUser,
@@ -26,6 +27,7 @@ import {
2627
renameChatRoom,
2728
updateChat,
2829
updateConfig,
30+
updateRoomPrompt,
2931
updateUserInfo,
3032
updateUserPassword,
3133
verifyUser,
@@ -61,6 +63,7 @@ router.get('/chatrooms', auth, async (req, res) => {
6163
uuid: r.roomId,
6264
title: r.title,
6365
isEdit: false,
66+
prompt: r.prompt,
6467
})
6568
})
6669
res.send({ status: 'Success', message: null, data: result })
@@ -97,6 +100,22 @@ router.post('/room-rename', auth, async (req, res) => {
97100
}
98101
})
99102

103+
router.post('/room-prompt', auth, async (req, res) => {
104+
try {
105+
const userId = req.headers.userId as string
106+
const { prompt, roomId } = req.body as { prompt: string; roomId: number }
107+
const success = await updateRoomPrompt(userId, roomId, prompt)
108+
if (success)
109+
res.send({ status: 'Success', message: 'Saved successfully', data: null })
110+
else
111+
res.send({ status: 'Fail', message: 'Saved Failed', data: null })
112+
}
113+
catch (error) {
114+
console.error(error)
115+
res.send({ status: 'Fail', message: 'Rename error', data: null })
116+
}
117+
})
118+
100119
router.post('/room-delete', auth, async (req, res) => {
101120
try {
102121
const userId = req.headers.userId as string
@@ -272,7 +291,11 @@ router.post('/chat', auth, async (req, res) => {
272291
router.post('/chat-process', [auth, limiter], async (req, res) => {
273292
res.setHeader('Content-type', 'application/octet-stream')
274293

275-
const { roomId, uuid, regenerate, prompt, options = {}, systemMessage, temperature, top_p } = req.body as RequestProps
294+
let { roomId, uuid, regenerate, prompt, options = {}, systemMessage, temperature, top_p } = req.body as RequestProps
295+
const userId = req.headers.userId as string
296+
const room = await getChatRoom(userId, roomId)
297+
if (room != null && isNotEmptyString(room.prompt))
298+
systemMessage = room.prompt
276299

277300
let lastResponse
278301
let result

service/src/storage/model.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ export class ChatRoom {
3737
roomId: number
3838
userId: string
3939
title: string
40+
prompt: string
4041
status: Status = Status.Normal
4142
constructor(userId: string, title: string, roomId: number) {
4243
this.userId = userId
4344
this.title = title
45+
this.prompt = undefined
4446
this.roomId = roomId
4547
}
4648
}

service/src/storage/mongo.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,28 @@ export async function deleteChatRoom(userId: string, roomId: number) {
7777
return result
7878
}
7979

80+
export async function updateRoomPrompt(userId: string, roomId: number, prompt: string) {
81+
const query = { userId, roomId }
82+
const update = {
83+
$set: {
84+
prompt,
85+
},
86+
}
87+
const result = await roomCol.updateOne(query, update)
88+
return result.modifiedCount > 0
89+
}
90+
8091
export async function getChatRooms(userId: string) {
8192
const cursor = await roomCol.find({ userId, status: { $ne: Status.Deleted } })
8293
const rooms = []
8394
await cursor.forEach(doc => rooms.push(doc))
8495
return rooms
8596
}
8697

98+
export async function getChatRoom(userId: string, roomId: number) {
99+
return await roomCol.findOne({ userId, roomId, status: { $ne: Status.Deleted } }) as ChatRoom
100+
}
101+
87102
export async function existsChatRoom(userId: string, roomId: number) {
88103
const room = await roomCol.findOne({ roomId, userId })
89104
return !!room

src/api/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ export function fetchRenameChatRoom<T = any>(title: string, roomId: number) {
134134
})
135135
}
136136

137+
export function fetchUpdateChatRoomPrompt<T = any>(prompt: string, roomId: number) {
138+
return post<T>({
139+
url: '/room-prompt',
140+
data: { prompt, roomId },
141+
})
142+
}
143+
137144
export function fetchDeleteChatRoom<T = any>(roomId: number) {
138145
return post<T>({
139146
url: '/room-delete',
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<script lang="ts" setup>
2+
import { computed, ref } from 'vue'
3+
import { NButton, NInput, NModal, NSpace, useMessage } from 'naive-ui'
4+
import { t } from '@/locales'
5+
import { fetchUpdateChatRoomPrompt } from '@/api'
6+
import { useChatStore } from '@/store'
7+
8+
const props = defineProps<Props>()
9+
const emit = defineEmits<Emit>()
10+
11+
const chatStore = useChatStore()
12+
const currentChatHistory = computed(() => chatStore.getChatHistoryByCurrentActive)
13+
const ms = useMessage()
14+
const testing = ref(false)
15+
const title = `Prompt For [${currentChatHistory.value?.title}]`
16+
17+
interface Props {
18+
visible: boolean
19+
roomId: string
20+
}
21+
22+
interface Emit {
23+
(e: 'update:visible', visible: boolean): void
24+
}
25+
26+
const show = computed({
27+
get() {
28+
return props.visible
29+
},
30+
set(visible: boolean) {
31+
emit('update:visible', visible)
32+
},
33+
})
34+
35+
async function handleSaveChatRoomPrompt() {
36+
if (!currentChatHistory.value || !currentChatHistory.value)
37+
return
38+
39+
testing.value = true
40+
try {
41+
const { message } = await fetchUpdateChatRoomPrompt(currentChatHistory.value.prompt ?? '', +props.roomId) as { status: string; message: string }
42+
ms.success(message)
43+
show.value = false
44+
}
45+
catch (error: any) {
46+
ms.error(error.message)
47+
}
48+
testing.value = false
49+
}
50+
</script>
51+
52+
<template>
53+
<NModal
54+
v-model:show="show" :auto-focus="false" class="custom-card" preset="card" :style="{ width: '600px' }" :title="title" size="huge"
55+
:bordered="false"
56+
>
57+
<!-- <template #header-extra>
58+
噢!
59+
</template> -->
60+
<NInput
61+
:value="currentChatHistory && currentChatHistory.prompt"
62+
type="textarea"
63+
:autosize="{ minRows: 4, maxRows: 10 }" placeholder="Prompt for this room, If empty will use Settings -> Advanced -> Role" @input="(val) => { if (currentChatHistory) currentChatHistory.prompt = val }"
64+
/>
65+
<template #footer>
66+
<NSpace justify="end">
67+
<NButton :loading="testing" type="success" @click="handleSaveChatRoomPrompt">
68+
{{ t('common.save') }}
69+
</NButton>
70+
</NSpace>
71+
</template>
72+
</NModal>
73+
</template>

0 commit comments

Comments
 (0)