Skip to content

Commit

Permalink
Merge branch 'Chanzhaoyu:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
jingfelix authored Mar 24, 2023
2 parents a4eb0a0 + 9023210 commit 9baf57a
Show file tree
Hide file tree
Showing 39 changed files with 443 additions and 101 deletions.
5 changes: 4 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Glob API URL
VITE_GLOB_API_URL=/api

VITE_APP_API_BASE_URL=http://localhost:3002/
VITE_APP_API_BASE_URL=http://127.0.0.1:3002/

# Whether long replies are supported, which may result in higher API fees
VITE_GLOB_OPEN_LONG_REPLY=false

# When you want to use PWA
VITE_GLOB_APP_PWA=false
25 changes: 25 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Web App",
"url": "http://localhost:1002",
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "Launch Service Server",
"runtimeExecutable": "${workspaceFolder}/service/node_modules/.bin/esno",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/service/src/index.ts",
"outFiles": ["${workspaceFolder}/service/**/*.js"],
"envFile": "${workspaceFolder}/service/.env"
}
]
}
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
## v2.10.8

`2023-03-23`

如遇问题,请删除 `node_modules` 重新安装依赖。

## Feature
- 显示回复消息原文的选项 [[yilozt](https://github.com/Chanzhaoyu/chatgpt-web/pull/672)]
- 添加单 `IP` 每小时请求限制。环境变量: `MAX_REQUEST_PER_HOUR` [[zhuxindong ](https://github.com/Chanzhaoyu/chatgpt-web/pull/718)]
- 前端添加角色设定,仅 `API` 方式可见 [[quzard](https://github.com/Chanzhaoyu/chatgpt-web/pull/768)]
- `OPENAI_API_MODEL` 变量现在对 `ChatGPTUnofficialProxyAPI` 也生效,注意:`Token``API` 的模型命名不一致,不能直接填入 `gpt-3.5` 或者 `gpt-4` [[hncboy](https://github.com/Chanzhaoyu/chatgpt-web/pull/632)]
- 添加繁体中文 `Prompts` [[PeterDaveHello](https://github.com/Chanzhaoyu/chatgpt-web/pull/796)]

## Enhancement
- 重置回答时滚动定位至该回答 [[shunyue1320](https://github.com/Chanzhaoyu/chatgpt-web/pull/781)]
-`API``gpt-4` 时增加可用的 `Max Tokens` [[simonwu53](https://github.com/Chanzhaoyu/chatgpt-web/pull/729)]
- 判断和忽略回复字符 [[liut](https://github.com/Chanzhaoyu/chatgpt-web/pull/474)]
- 切换会话时,自动聚焦输入框 [[JS-an](https://github.com/Chanzhaoyu/chatgpt-web/pull/735)]
- 渲染的链接新窗口打开
- 查询余额可选 `API_BASE_URL` 代理地址
- `config` 接口添加验证防止被无限制调用
- `PWA` 默认不开启,现在需手动修改 `.env` 文件 `VITE_GLOB_APP_PWA` 变量
- 当网络连接时,刷新页面,`500` 错误页自动跳转到主页

## BugFix
- `scrollToBottom` 调回 `scrollToBottomIfAtBottom` [[shunyue1320](https://github.com/Chanzhaoyu/chatgpt-web/pull/771)]
- 重置异常的 `loading` 会话

## Common
- 创建 `start.cmd``windows` 下也可以运行 [vulgatecnn](https://github.com/Chanzhaoyu/chatgpt-web/pull/656)]
- 添加 `visual-studio-code` 中调试配置 [[ChandlerVer5](https://github.com/Chanzhaoyu/chatgpt-web/pull/296)]
- 修复文档中 `docker` 端口为本地 [[kilvn](https://github.com/Chanzhaoyu/chatgpt-web/pull/802)]
## Other
- 依赖更新


## v2.10.7

`2023-03-17`
Expand Down
6 changes: 3 additions & 3 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,10 @@ pnpm dev
docker build -t chatgpt-web .

# foreground operation
docker run --name chatgpt-web --rm -it -p 3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web
docker run --name chatgpt-web --rm -it -p 127.0.0.1:3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web

# background operation
docker run --name chatgpt-web -d -p 3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web
docker run --name chatgpt-web -d -p 127.0.0.1:3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web

# running address
http://localhost:3002/
Expand All @@ -205,7 +205,7 @@ services:
app:
image: chenzhaoyu94/chatgpt-web # always use latest, pull the tag image again when updating
ports:
- 3002:3002
- 127.0.0.1:3002:3002
environment:
# one of two
OPENAI_API_KEY: xxxxxx
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ pnpm dev
通用:

- `AUTH_SECRET_KEY` 访问权限密钥,可选
- `MAX_REQUEST_PER_HOUR` 每小时最大请求次数,可选,默认无限
- `TIMEOUT_MS` 超时,单位毫秒,可选
- `SOCKS_PROXY_HOST``SOCKS_PROXY_PORT` 一起时生效,可选
- `SOCKS_PROXY_PORT``SOCKS_PROXY_HOST` 一起时生效,可选
Expand All @@ -190,10 +191,10 @@ pnpm dev
docker build -t chatgpt-web .

# 前台运行
docker run --name chatgpt-web --rm -it -p 3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web
docker run --name chatgpt-web --rm -it -p 127.0.0.1:3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web

# 后台运行
docker run --name chatgpt-web -d -p 3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web
docker run --name chatgpt-web -d -p 127.0.0.1:3002:3002 --env OPENAI_API_KEY=your_api_key chatgpt-web

# 运行地址
http://localhost:3002/
Expand All @@ -210,7 +211,7 @@ services:
app:
image: chenzhaoyu94/chatgpt-web # 总是使用 latest ,更新时重新 pull 该 tag 镜像即可
ports:
- 3002:3002
- 127.0.0.1:3002:3002
environment:
# 二选一
OPENAI_API_KEY: sk-xxx
Expand All @@ -224,6 +225,8 @@ services:
API_REVERSE_PROXY: xxx
# 访问权限密钥,可选
AUTH_SECRET_KEY: xxx
# 每小时最大请求次数,可选,默认无限
MAX_REQUEST_PER_HOUR: 0
# 超时,单位毫秒,可选
TIMEOUT_MS: 60000
# Socks代理,可选,和 SOCKS_PROXY_PORT 一起时生效
Expand All @@ -245,6 +248,7 @@ services:
| --------------------- | ---------------------- | -------------------------------------------------------------------------------------------------- |
| `PORT` | 必填 | 默认 `3002`
| `AUTH_SECRET_KEY` | 可选 | 访问权限密钥 |
| `MAX_REQUEST_PER_HOUR` | 可选 | 每小时最大请求次数,可选,默认无限 |
| `TIMEOUT_MS` | 可选 | 超时时间,单位毫秒 |
| `OPENAI_API_KEY` | `OpenAI API` 二选一 | 使用 `OpenAI API` 所需的 `apiKey` [(获取 apiKey)](https://platform.openai.com/overview) |
| `OPENAI_ACCESS_TOKEN` | `Web API` 二选一 | 使用 `Web API` 所需的 `accessToken` [(获取 accessToken)](https://chat.openai.com/api/auth/session) |
Expand Down
2 changes: 2 additions & 0 deletions docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ services:
API_REVERSE_PROXY: xxx
# 访问权限密钥,可选
AUTH_SECRET_KEY: xxx
# 每小时最大请求次数,可选,默认无限
MAX_REQUEST_PER_HOUR: 0
# 超时,单位毫秒,可选
TIMEOUT_MS: 60000
# Socks代理,可选,和 SOCKS_PROXY_PORT 一起时生效
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chatgpt-web",
"version": "2.10.7",
"version": "2.10.8",
"private": false,
"description": "ChatGPT Web",
"author": "ChenZhaoYu <[email protected]>",
Expand Down
4 changes: 4 additions & 0 deletions service/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ API_REVERSE_PROXY=
# timeout
TIMEOUT_MS=100000

# Rate Limit
MAX_REQUEST_PER_HOUR=

# Secret key
AUTH_SECRET_KEY=

Expand All @@ -27,3 +30,4 @@ SOCKS_PROXY_PORT=

# HTTPS PROXY
HTTPS_PROXY=

5 changes: 3 additions & 2 deletions service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"scripts": {
"start": "esno ./src/index.ts",
"dev": "esno watch ./src/index.ts",
"prod": "esno ./build/index.js",
"prod": "node ./build/index.mjs",
"build": "pnpm clean && tsup",
"clean": "rimraf build",
"lint": "eslint .",
Expand All @@ -25,10 +25,11 @@
},
"dependencies": {
"axios": "^1.3.4",
"chatgpt": "^5.0.10",
"chatgpt": "^5.1.2",
"dotenv": "^16.0.3",
"esno": "^0.16.3",
"express": "^4.18.2",
"express-rate-limit": "^6.7.0",
"https-proxy-agent": "^5.0.1",
"isomorphic-fetch": "^3.0.0",
"node-fetch": "^3.3.0",
Expand Down
25 changes: 18 additions & 7 deletions service/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 36 additions & 14 deletions service/src/chatgpt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ import 'isomorphic-fetch'
import type { ChatGPTAPIOptions, ChatMessage, SendMessageOptions } from 'chatgpt'
import { ChatGPTAPI, ChatGPTUnofficialProxyAPI } from 'chatgpt'
import { SocksProxyAgent } from 'socks-proxy-agent'
import { HttpsProxyAgent } from 'https-proxy-agent'
import httpsProxyAgent from 'https-proxy-agent'
import fetch from 'node-fetch'
import axios from 'axios'
import { sendResponse } from '../utils'
import { isNotEmptyString } from '../utils/is'
import type { ApiModel, ChatContext, ChatGPTUnofficialProxyAPIOptions, ModelConfig } from '../types'
import type { RequestOptions } from './types'

const { HttpsProxyAgent } = httpsProxyAgent

dotenv.config()

const ErrorCodeMessage: Record<string, string> = {
401: '[OpenAI] 提供错误的API密钥 | Incorrect API key provided',
Expand All @@ -19,21 +24,20 @@ const ErrorCodeMessage: Record<string, string> = {
500: '[OpenAI] 服务器繁忙,请稍后再试 | Internal Server Error',
}

dotenv.config()

const timeoutMs: number = !isNaN(+process.env.TIMEOUT_MS) ? +process.env.TIMEOUT_MS : 30 * 1000

let apiModel: ApiModel

if (!process.env.OPENAI_API_KEY && !process.env.OPENAI_ACCESS_TOKEN)
if (!isNotEmptyString(process.env.OPENAI_API_KEY) && !isNotEmptyString(process.env.OPENAI_ACCESS_TOKEN))
throw new Error('Missing OPENAI_API_KEY or OPENAI_ACCESS_TOKEN environment variable')

let api: ChatGPTAPI | ChatGPTUnofficialProxyAPI

(async () => {
// More Info: https://github.com/transitive-bullshit/chatgpt-api

if (process.env.OPENAI_API_KEY) {
if (isNotEmptyString(process.env.OPENAI_API_KEY)) {
const OPENAI_API_BASE_URL = process.env.OPENAI_API_BASE_URL
const OPENAI_API_MODEL = process.env.OPENAI_API_MODEL
const model = isNotEmptyString(OPENAI_API_MODEL) ? OPENAI_API_MODEL : 'gpt-3.5-turbo'

Expand All @@ -43,19 +47,35 @@ let api: ChatGPTAPI | ChatGPTUnofficialProxyAPI
debug: true,
}

if (isNotEmptyString(process.env.OPENAI_API_BASE_URL))
options.apiBaseUrl = process.env.OPENAI_API_BASE_URL
// increase max token limit if use gpt-4
if (model.toLowerCase().includes('gpt-4')) {
// if use 32k model
if (model.toLowerCase().includes('32k')) {
options.maxModelTokens = 32768
options.maxResponseTokens = 8192
}
else {
options.maxModelTokens = 8192
options.maxResponseTokens = 2048
}
}

if (isNotEmptyString(OPENAI_API_BASE_URL))
options.apiBaseUrl = `${OPENAI_API_BASE_URL}/v1`

setupProxy(options)

api = new ChatGPTAPI({ ...options })
apiModel = 'ChatGPTAPI'
}
else {
const OPENAI_API_MODEL = process.env.OPENAI_API_MODEL
const options: ChatGPTUnofficialProxyAPIOptions = {
accessToken: process.env.OPENAI_ACCESS_TOKEN,
debug: true,
}
if (isNotEmptyString(OPENAI_API_MODEL))
options.model = OPENAI_API_MODEL

if (isNotEmptyString(process.env.API_REVERSE_PROXY))
options.apiReverseProxyUrl = process.env.API_REVERSE_PROXY
Expand All @@ -67,17 +87,19 @@ let api: ChatGPTAPI | ChatGPTUnofficialProxyAPI
}
})()

async function chatReplyProcess(
message: string,
lastContext?: { conversationId?: string; parentMessageId?: string },
process?: (chat: ChatMessage) => void,
) {
async function chatReplyProcess(options: RequestOptions) {
const { message, lastContext, process, systemMessage } = options
try {
let options: SendMessageOptions = { timeoutMs }

if (lastContext) {
if (apiModel === 'ChatGPTAPI') {
if (isNotEmptyString(systemMessage))
options.systemMessage = systemMessage
}

if (lastContext != null) {
if (apiModel === 'ChatGPTAPI')
options = { parentMessageId: lastContext.parentMessageId }
options.parentMessageId = lastContext.parentMessageId
else
options = { ...lastContext }
}
Expand Down
8 changes: 8 additions & 0 deletions service/src/chatgpt/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { ChatMessage } from 'chatgpt'

export interface RequestOptions {
message: string
lastContext?: { conversationId?: string; parentMessageId?: string }
process?: (chat: ChatMessage) => void
systemMessage?: string
}
Loading

0 comments on commit 9baf57a

Please sign in to comment.