Compare commits

...

13 Commits

Author SHA1 Message Date
Rafi
8175f199d2 Support GPT-4 2023-03-27 22:17:19 +08:00
Wong Saang
f8c2f396c1 Merge pull request #70 from Paramon/main
#50 add platform to docker-compose
2023-03-25 21:03:50 +08:00
Andrii Paramonov
8217647df8 #50 add platform 2023-03-24 16:44:00 +02:00
Rafi
288c9eeeca Change the functionality of custom API key to be controlled by the admin panel to determine whether it is enabled or not. 2023-03-24 15:43:01 +08:00
Rafi
4d09ff7c8a Added env var NUXT_PUBLIC_CUSTOM_API_KEY to docs 2023-03-24 14:32:38 +08:00
Rafi
5fa059017c Support controlling whether to enable the API Key setting module through environment variables. 2023-03-24 14:22:45 +08:00
Rafi
323f10844b Modify the placeholder of the default prompt for web search to solve the problem of not providing web search results to ChatGPT 2023-03-24 11:22:51 +08:00
Rafi
ee035390db add default prompt to web search 2023-03-23 18:48:08 +08:00
Wong Saang
be743bf799 Update README.md 2023-03-23 17:13:34 +08:00
Wong Saang
a59f84f2bf Update README.md 2023-03-23 17:12:59 +08:00
Rafi
ed0cf2997d update readme 2023-03-23 17:07:49 +08:00
Rafi
7f00c74097 Added wsgi-server environment variable EMAIL_FROM to docker-compose.yml and readme 2023-03-23 15:31:26 +08:00
Rafi
f007417fa4 add update info to readme 2023-03-23 12:53:08 +08:00
13 changed files with 98 additions and 39 deletions

View File

@@ -1,14 +1,22 @@
<p align="center">
<img alt="demo" src="./demos/demo.gif?v=1">
</p>
<div align="center">
<h1>ChatGPT UI</h1>
</div>
[English](./README.md) | [中文](./docs/zh/README.md)
# ChatGPT UI
A ChatGPT web client that supports multiple users, multiple database connections for persistent data storage, supports i18n. Provides Docker images and quick deployment scripts.
https://user-images.githubusercontent.com/46235412/227156264-ca17ab17-999b-414f-ab06-3f75b5235bfe.mp4
## 📢Updates
<details open>
<summary><strong>2023-03-23</strong></summary>
Added web search capability to generate more relevant and up-to-date answers from ChatGPT!
This feature is off by default, you can turn it on in `Chat->Settings` in the admin panel, there is a record `open_web_search` in Settings, set its value to True.
</details>
<details open>
<summary><strong>2023-03-15</strong></summary>
@@ -115,6 +123,7 @@ services:
# - EMAIL_HOST_USER=
# - EMAIL_HOST_PASSWORD=
# - EMAIL_USE_TLS=True
# - EMAIL_FROM=no-reply@example.com #Default sender email address
ports:
- '8000:8000'
networks:
@@ -191,4 +200,4 @@ Build the application for production:
```bash
yarn build
```
```

View File

@@ -1,11 +1,15 @@
<script setup>
const dialog = ref(false)
const currentModel = useCurrentModel()
const availableModels = [
DEFAULT_MODEL.name
'gpt-3.5-turbo',
'gpt-4'
]
const currentModelDefault = ref(MODELS[currentModel.value.name])
watch(currentModel, (newVal, oldVal) => {
currentModelDefault.value = MODELS[newVal.name]
saveCurrentModel(newVal)
}, { deep: true })
@@ -83,7 +87,7 @@ watch(currentModel, (newVal, oldVal) => {
single-line
density="compact"
type="number"
max="2048"
:max="currentModelDefault.total_tokens"
step="1"
style="width: 100px"
class="flex-grow-0"
@@ -93,7 +97,7 @@ watch(currentModel, (newVal, oldVal) => {
<v-col cols="12">
<v-slider
v-model="currentModel.max_tokens"
:max="2048"
:max="currentModelDefault.total_tokens"
:step="1"
hide-details
>

View File

@@ -1,5 +1,5 @@
export const useModels = () => useState('models', () => getStoredModels())
// export const useModels = () => useState('models', () => getStoredModels())
export const useCurrentModel = () => useState('currentModel', () => getCurrentModel())

BIN
demos/demo.mp4 Normal file

Binary file not shown.

View File

@@ -1,6 +1,7 @@
version: '3'
services:
client:
platform: linux/x86_64
image: wongsaang/chatgpt-ui-client:latest
environment:
- SERVER_DOMAIN=http://backend-web-server
@@ -15,6 +16,7 @@ services:
- chatgpt_ui_network
restart: always
backend-wsgi-server:
platform: linux/x86_64
image: wongsaang/chatgpt-ui-wsgi-server:latest
environment:
- APP_DOMAIN=${APP_DOMAIN:-localhost:9000}
@@ -29,12 +31,14 @@ services:
# - EMAIL_HOST_USER=
# - EMAIL_HOST_PASSWORD=
# - EMAIL_USE_TLS=True
# - EMAIL_FROM=no-reply@example.com #Default sender email address
ports:
- '${WSGI_PORT:-8000}:8000'
networks:
- chatgpt_ui_network
restart: always
backend-web-server:
platform: linux/x86_64
image: wongsaang/chatgpt-ui-web-server:latest
environment:
- BACKEND_URL=http://backend-wsgi-server:8000
@@ -48,4 +52,4 @@ services:
networks:
chatgpt_ui_network:
driver: bridge
driver: bridge

View File

@@ -1,14 +1,21 @@
<p align="center">
<img alt="demo" src="../../demos/demo.gif?v=1">
</p>
<div align="center">
<h1>ChatGPT UI</h1>
</div>
[English](../../README.md) | [中文](./docs/zh/README.md)
# ChatGPT UI
ChatGPT Web 客户端,支持多用户,支持 Mysql、PostgreSQL 等多种数据库连接进行数据持久化存储,支持多语言。提供 Docker 镜像和快速部署脚本。
https://user-images.githubusercontent.com/46235412/227156264-ca17ab17-999b-414f-ab06-3f75b5235bfe.mp4
## 📢 更新
<details open>
<summary><strong>2023-03-23</strong></summary>
增加网页搜索能力,使得 ChatGPT 生成的回答更与时俱进!
该功能默认处于关闭状态,你可以在管理后台的 `Chat->Settings` 中开启它,在 Settings 中有一个 `open_web_search` 的记录,把它的值设置为 True。
</details>
<details open>
<summary><strong>2023-03-15</strong></summary>
@@ -113,6 +120,7 @@ services:
# - EMAIL_HOST_USER=
# - EMAIL_HOST_PASSWORD=
# - EMAIL_USE_TLS=True
# - EMAIL_FROM=no-reply@example.com #默认发件邮箱地址
ports:
- '8000:8000'
networks:
@@ -189,4 +197,4 @@ Build the application for production:
```bash
yarn build
```
```

View File

@@ -35,6 +35,7 @@
"delete": "Delete",
"signOut": "Sign out",
"webSearch": "Web Search",
"webSearchDefaultPrompt": "Web search results:\n\n[web_results]\nCurrent date: [current_date]\n\nInstructions: Using the provided web search results, write a comprehensive reply to the given query. Make sure to cite results using [[number](URL)] notation after the reference. If the provided search results refer to multiple subjects with the same name, write separate answers for each subject.\nQuery: [query]",
"welcomeScreen": {
"introduction1": "is an unofficial client for ChatGPT, but uses the official OpenAI API.",
"introduction2": "You will need an OpenAI API Key before you can use this client.",

View File

@@ -35,6 +35,7 @@
"delete": "删除",
"signOut": "退出登录",
"webSearch": "网页搜索",
"webSearchDefaultPrompt": "网络搜索结果:\n\n[web_results]\n当前日期[current_date]\n\n说明使用提供的网络搜索结果对给定的查询写出全面的回复。确保在引用参考文献后使用 [[number](URL)] 符号进行引用结果. 如果提供的搜索结果涉及到多个具有相同名称的主题,请针对每个主题编写单独的答案。\n查询[query]",
"welcomeScreen": {
"introduction1": "是一个非官方的ChatGPT客户端但使用OpenAI的官方API",
"introduction2": "在使用本客户端之前您需要一个OpenAI API密钥。",

View File

@@ -98,6 +98,15 @@ const signOut = async () => {
}
}
const settings = useSettings()
const showApiKeySetting = ref(false)
watchEffect(() => {
if (settings.value) {
const settingsValue = toRaw(settings.value)
showApiKeySetting.value = settingsValue.open_api_key_setting && settingsValue.open_api_key_setting === 'True'
}
})
onMounted(async () => {
loadConversations()
loadSettings()
@@ -239,6 +248,10 @@ onMounted(async () => {
</v-card>
</v-dialog>
<ApiKeyDialog
v-if="showApiKeySetting"
/>
<ModelParameters/>
<v-menu

View File

@@ -1,5 +1,5 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
const appName = 'ChatGPT UI'
const appName = process.env.NUXT_PUBLIC_APP_NAME ?? 'ChatGPT UI'
export default defineNuxtConfig({
dev: false,
@@ -14,6 +14,7 @@ export default defineNuxtConfig({
appName: appName,
typewriter: false,
typewriterDelay: 50,
customApiKey: false
}
},
build: {

View File

@@ -52,15 +52,15 @@ const fetchReply = async (message) => {
ctrl = new AbortController()
let webSearchParams = {}
console.log(enableWebSearch.value)
if (enableWebSearch.value) {
webSearchParams['web_search'] = {
ua: navigator.userAgent
ua: navigator.userAgent,
default_prompt: $i18n.t('webSearchDefaultPrompt')
}
}
const data = Object.assign({}, currentModel.value, {
openaiApiKey: openaiApiKey.value,
openaiApiKey: enableCustomApiKey.value ? openaiApiKey.value : null,
message: message,
conversationId: currentConversation.value.id
}, webSearchParams)
@@ -90,12 +90,13 @@ const fetchReply = async (message) => {
throw err;
},
async onmessage(message) {
// console.log(message)
const event = message.event
const data = JSON.parse(message.data)
if (event === 'error') {
throw new Error(data.error);
abortFetch()
showSnackbar(data.error)
return;
}
if (event === 'userMessageId') {
@@ -165,6 +166,7 @@ const deleteMessage = (index) => {
const showWebSearchToggle = ref(false)
const enableWebSearch = ref(false)
const enableCustomApiKey = ref(false)
const settings = useSettings()
@@ -172,6 +174,7 @@ watchEffect(() => {
if (settings.value) {
const settingsValue = toRaw(settings.value)
showWebSearchToggle.value = settingsValue.open_web_search && settingsValue.open_web_search === 'True'
enableCustomApiKey.value = settingsValue.open_api_key_setting && settingsValue.open_api_key_setting === 'True'
}
})

View File

@@ -5,11 +5,25 @@ export const STORAGE_KEY = {
OPENAI_API_KEY: 'openai_api_key',
}
export const DEFAULT_MODEL = {
name: 'gpt-3.5-turbo',
frequency_penalty: 0.0,
presence_penalty: 0.0,
max_tokens: 1000,
temperature: 0.7,
top_p: 1.0
}
export const MODELS = {
'gpt-3.5-turbo': {
name: 'gpt-3.5-turbo',
frequency_penalty: 0.0,
presence_penalty: 0.0,
total_tokens: 4096,
max_tokens: 1000,
temperature: 0.7,
top_p: 1.0
},
'gpt-4': {
name: 'gpt-4',
frequency_penalty: 0.0,
presence_penalty: 0.0,
total_tokens: 8192,
max_tokens: 2000,
temperature: 0.7,
top_p: 1.0
}
}
export const DEFAULT_MODEL_NAME = 'gpt-3.5-turbo'

View File

@@ -1,3 +1,4 @@
import {MODELS} from "~/utils/enums";
const get = (key) => {
let val = localStorage.getItem(key)
@@ -17,13 +18,13 @@ export const setModels = (val) => {
models.value = val
}
export const getStoredModels = () => {
let models = get(STORAGE_KEY.MODELS)
if (!models) {
models = [DEFAULT_MODEL]
}
return models
}
// export const getStoredModels = () => {
// let models = get(STORAGE_KEY.MODELS)
// if (!models) {
// models = [DEFAULT_MODEL]
// }
// return models
// }
export const saveCurrentModel = (val) => {
set(STORAGE_KEY.CURRENT_MODEL, val)
@@ -32,7 +33,7 @@ export const saveCurrentModel = (val) => {
export const getCurrentModel = () => {
let model = get(STORAGE_KEY.CURRENT_MODEL)
if (!model) {
model = DEFAULT_MODEL
model = MODELS[DEFAULT_MODEL_NAME]
}
return model
}