Compare commits

..

30 Commits

Author SHA1 Message Date
ChenZhaoYu
797cc7461b Merge branch 'dev' 2023-02-14 10:09:10 +08:00
ChenZhaoYu
58547d1b58 chore: version 2.1.0 2023-02-14 10:08:31 +08:00
Redon
c933a851f4 Merge pull request #21 from Chanzhaoyu/dev
v2.1.0
2023-02-14 10:05:21 +08:00
ChenZhaoYu
86fcbbff0b feat: 上限文联想改为前端进行 2023-02-14 10:04:32 +08:00
ChenZhaoYu
5d1f8519c2 chore: typo description 2023-02-14 08:45:07 +08:00
ChenZhaoYu
3c21068150 chore: update readme 2023-02-13 21:07:34 +08:00
ChenZhaoYu
cd03a71ef1 chore: update deps 2023-02-13 21:02:25 +08:00
Redon
1d74717beb Merge pull request #20 from Chanzhaoyu/dev
fix: 修复代码提交前验证流程
2023-02-13 20:55:55 +08:00
ChenZhaoYu
e35abb1c98 fix: 修复代码提交前验证流程 2023-02-13 20:55:26 +08:00
Redon
b4b0f65158 Merge pull request #19 from Chanzhaoyu/dev
chore: 移除打包测试
2023-02-13 20:46:37 +08:00
ChenZhaoYu
910c19b02e chore: 移除打包测试 2023-02-13 20:42:45 +08:00
Redon
32049fbf18 Merge pull request #18 from Chanzhaoyu/dev
chore: key invalid tips
2023-02-13 20:34:08 +08:00
ChenZhaoYu
817a4842ac chore: key invalid tips 2023-02-13 20:33:36 +08:00
Redon
0cd120ec5b Merge pull request #17 from Chanzhaoyu/dev
chore: 优化 `service` 内命令
2023-02-13 20:24:17 +08:00
ChenZhaoYu
007763f7d7 chore: 忽略 service 文件夹 2023-02-13 20:13:19 +08:00
ChenZhaoYu
3debaec4b2 chore: 添加 service 打包编译设置 2023-02-13 20:10:08 +08:00
ChenZhaoYu
35f353c1f7 chore: 补全配置 2023-02-13 19:56:11 +08:00
Redon
3ac6746930 Merge pull request #16 from Chanzhaoyu/dev
fix: 上下文按钮失效
2023-02-13 19:40:46 +08:00
ChenZhaoYu
9b556e4833 chore: 添加对于模型的提示 2023-02-13 19:30:26 +08:00
ChenZhaoYu
071283c007 fix: 清除上下文按钮失效的问题 2023-02-13 19:25:59 +08:00
Redon
854261ef86 Merge pull request #15 from Chanzhaoyu/dev
chore: 修复报错和自动化错误
2023-02-13 19:20:51 +08:00
ChenZhaoYu
633e9ad8e2 chore: cli error 2023-02-13 19:18:01 +08:00
ChenZhaoYu
47dd6c9801 fix: type-check 2023-02-13 19:17:55 +08:00
Redon
0eb9df6d31 Merge pull request #14 from Chanzhaoyu/dev
chore: 优化部份问题
2023-02-13 19:11:49 +08:00
ChenZhaoYu
8bfbe6f7df feat: 调整页面样式 2023-02-13 19:10:21 +08:00
ChenZhaoYu
43e8635e7f chore: README.md 2023-02-13 19:09:34 +08:00
Redon
b7542c70cb Create ci.yml
chore: test cli
2023-02-13 18:58:26 +08:00
Redon
b594ec5de1 Merge pull request #12 from Chanzhaoyu/dev
chore: typo
2023-02-13 18:41:27 +08:00
ChenZhaoYu
9a9b154040 chore: typo 2023-02-13 18:21:26 +08:00
Redon
12681b1a05 Update README.md 2023-02-13 16:48:24 +08:00
26 changed files with 591 additions and 208 deletions

47
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Setup
run: npm i -g @antfu/ni
- name: Install
run: nci
- name: Lint
run: nr lint:fix
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Setup
run: npm i -g @antfu/ni
- name: Install
run: nci
- name: Typecheck
run: nr type-check

2
.husky/commit-msg Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm exec commitlint --config .commitlintrc.json --edit "${1}"
npx --no -- commitlint --edit

2
.husky/pre-commit Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm exec lint-staged
npx lint-staged

View File

@@ -33,6 +33,8 @@
"rushstack",
"Sider",
"tailwindcss",
"tsup",
"Typecheck",
"unplugin",
"VITE",
"vueuse"

View File

@@ -1,3 +1,14 @@
## v2.1.0
`2023-02-14`
### Enhancement
- 更新依赖至最新
- 联想功能移动至前端提交,后端只做转发
### BugFix
- 修复部份项目检测有关 `Bug`
- 修复清除上下文按钮失效
## v2.0.0
`2023-02-13`

26
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,26 @@
# 指南
## Commit 指南
Commit messages 请遵循[conventional-changelog 标准](https://www.conventionalcommits.org/en/v1.0.0/)
```bash
<类型>[可选 范围]: <描述>
[可选 正文]
[可选 脚注]
```
### Commit 类型
以下是 commit 类型列表:
- feat: 新特性或功能
- fix: 缺陷修复
- docs: 文档更新
- style: 代码风格或者组件样式更新
- refactor: 代码重构,不引入新功能和缺陷修复
- perf: 性能优化
- test: 单元测试
- chore: 其他不修改 src 或测试文件的提交

View File

@@ -1,19 +1,21 @@
# ChatGPT Web Bot
中文 | [English](./README.en.md)
# ChatGPT Web
使用 express 和 vue3 搭建的 ChartGPT 演示网页
![cover](./docs/cover-2.png)
## Route Map
[x] 多会话
> 提示:目前 `OpenAI` 开放的模型最高只有 `GPT-3`,和现在网页所使用的 `GPT-3.5` 或 `GPT-4` 有很大差距,需要等官方开放最新的模型接口。
[x] 多语言
## 待实现路线
[x] 多会话储存和上下文逻辑
[x] 主题
[x] 对代码等消息类型的格式化美化处理
[x] 用户模块
[x] 用户模块(注册、登录、个人中心)
[x] 界面多语言
[x] 界面主题
[x] More...
@@ -33,7 +35,7 @@ node -v
npm install pnpm -g
```
### OpenAI API KEy
### OpenAI API Key
获取 [OpenAI API key](https://platform.openai.com/overview) 并填写到本地环境变量
```
# service/.env 文件
@@ -76,12 +78,24 @@ pnpm dev
```
## 打包
### 后端服务
> 如果你不需要本项目的 `node` 接口,可以省略如下操作
复制 `service` 文件夹到你有 `node` 服务环境的服务器上。(搜索关键字:`express部署`
复制 `service` 文件夹到你有 `node` 服务环境的服务器上。(搜索关键字:`express部署`
操作上述 `安装``运行` 服务。
```shell
# 安装
pnpm install
# 打包
pnpm build
# 运行
pnpm prod
```
PS: 不进行打包,直接在服务器上运行 `pnpm start` 也可
### 网页
根目录下运行以下命令,然后将 `dist` 文件夹复制到你的托管服务器上
@@ -91,6 +105,10 @@ pnpm build
```
### 常见问题
Q: 为什么 `Git` 提交总是报错?
A: 因为有提交信息验证,请遵循 [Commit 指南](./CONTRIBUTING.md)
Q: 如果只使用前端页面,在哪里改请求接口?
A: 根目录下 `.env` 文件中的 `VITE_GLOB_API_URL` 字段。

View File

@@ -1,13 +1,13 @@
{
"name": "chatgpt-web",
"version": "2.0.0",
"version": "2.1.0",
"private": false,
"description": "ChatGPT Web Bot",
"author": "ChenZhaoYu <chenzhaoyu1994@gami.com>",
"description": "ChatGPT Web",
"author": "ChenZhaoYu <chenzhaoyu1994@gmail.com>",
"keywords": [
"chatgpt-web",
"chatgpt",
"chatbot",
"web",
"vue"
],
"scripts": {
@@ -28,8 +28,8 @@
},
"devDependencies": {
"@antfu/eslint-config": "^0.35.2",
"@commitlint/cli": "^17.4.2",
"@commitlint/config-conventional": "^17.4.2",
"@commitlint/cli": "^17.4.3",
"@commitlint/config-conventional": "^17.4.3",
"@iconify/vue": "^4.1.0",
"@types/node": "^18.13.0",
"@vitejs/plugin-vue": "^4.0.0",
@@ -47,9 +47,8 @@
"vue-tsc": "^1.0.24"
},
"lint-staged": {
"*.{js,ts,jsx,tsx,vue}": [
"pnpm run lint:fix",
"pnpm run type-check"
"*.{ts,tsx,vue}": [
"pnpm lint:fix"
]
}
}

28
pnpm-lock.yaml generated
View File

@@ -2,8 +2,8 @@ lockfileVersion: 5.4
specifiers:
'@antfu/eslint-config': ^0.35.2
'@commitlint/cli': ^17.4.2
'@commitlint/config-conventional': ^17.4.2
'@commitlint/cli': ^17.4.3
'@commitlint/config-conventional': ^17.4.3
'@iconify/vue': ^4.1.0
'@types/node': ^18.13.0
'@vitejs/plugin-vue': ^4.0.0
@@ -30,8 +30,8 @@ dependencies:
devDependencies:
'@antfu/eslint-config': 0.35.2_7kw3g6rralp5ps6mg3uyzz6azm
'@commitlint/cli': 17.4.2
'@commitlint/config-conventional': 17.4.2
'@commitlint/cli': 17.4.3
'@commitlint/config-conventional': 17.4.3
'@iconify/vue': 4.1.0_vue@3.2.47
'@types/node': 18.13.0
'@vitejs/plugin-vue': 4.0.0_vite@4.1.1+vue@3.2.47
@@ -185,13 +185,13 @@ packages:
'@babel/helper-validator-identifier': 7.19.1
to-fast-properties: 2.0.0
/@commitlint/cli/17.4.2:
resolution: {integrity: sha512-0rPGJ2O1owhpxMIXL9YJ2CgPkdrFLKZElIZHXDN8L8+qWK1DGH7Q7IelBT1pchXTYTuDlqkOTdh//aTvT3bSUA==}
/@commitlint/cli/17.4.3:
resolution: {integrity: sha512-IPTS7AZuBHgD0gl24El8HwuDM9zJN9JLa5KmZUQoFD1BQeGGdzAYJOnAr85CeJWpTDok0BGHDL0+4odnH0iTyA==}
engines: {node: '>=v14'}
hasBin: true
dependencies:
'@commitlint/format': 17.4.0
'@commitlint/lint': 17.4.2
'@commitlint/lint': 17.4.3
'@commitlint/load': 17.4.2
'@commitlint/read': 17.4.2
'@commitlint/types': 17.4.0
@@ -205,8 +205,8 @@ packages:
- '@swc/wasm'
dev: true
/@commitlint/config-conventional/17.4.2:
resolution: {integrity: sha512-JVo1moSj5eDMoql159q8zKCU8lkOhQ+b23Vl3LVVrS6PXDLQIELnJ34ChQmFVbBdSSRNAbbXnRDhosFU+wnuHw==}
/@commitlint/config-conventional/17.4.3:
resolution: {integrity: sha512-8EsY2iDw74hCk3hIQSg7/E0R8/KtPjnFPZVwmmHxcjhZjkSykmxysefICPDnbI3xgxfov0zwL1WKDHM8zglJdw==}
engines: {node: '>=v14'}
dependencies:
conventional-changelog-conventionalcommits: 5.0.0
@@ -253,13 +253,13 @@ packages:
semver: 7.3.8
dev: true
/@commitlint/lint/17.4.2:
resolution: {integrity: sha512-HcymabrdBhsDMNzIv146+ZPNBPBK5gMNsVH+el2lCagnYgCi/4ixrHooeVyS64Fgce2K26+MC7OQ4vVH8wQWVw==}
/@commitlint/lint/17.4.3:
resolution: {integrity: sha512-GnPsqEYmXIB/MaBhRMzkiDJWyjuLrKad4xoxKO4N6Kc19iqjR4DPc/bl2dxeW9kUmtrAtefOzIEzJAevpA5y2w==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/is-ignored': 17.4.2
'@commitlint/parse': 17.4.2
'@commitlint/rules': 17.4.2
'@commitlint/rules': 17.4.3
'@commitlint/types': 17.4.0
dev: true
@@ -323,8 +323,8 @@ packages:
resolve-global: 1.0.0
dev: true
/@commitlint/rules/17.4.2:
resolution: {integrity: sha512-OGrPsMb9Fx3/bZ64/EzJehY9YDSGWzp81Pj+zJiY+r/NSgJI3nUYdlS37jykNIugzazdEXfMtQ10kmA+Kx2pZQ==}
/@commitlint/rules/17.4.3:
resolution: {integrity: sha512-xHReDfE3Z+O9p1sXeEhPRSk4FifBsC4EbXzvQ4aa0ykQe+n/iZDd4CrFC/Oiv2K9BU4ZnFHak30IbMLa4ks1Rw==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/ensure': 17.4.0

View File

@@ -1,2 +1,3 @@
# OpenAI API Key
OPENAI_API_KEY=
# OpenAI API Key - https://platform.openai.com/overview
# e.g: This key is invalid
OPENAI_API_KEY='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'

View File

@@ -1,4 +1,5 @@
{
"root": true,
"ignorePatterns": ["build"],
"extends": ["@antfu"]
}

2
service/.gitignore vendored
View File

@@ -27,3 +27,5 @@ coverage
*.njsproj
*.sln
*.sw?
build

1
service/.npmrc Normal file
View File

@@ -0,0 +1 @@
enable-pre-post-scripts=true

View File

@@ -2,23 +2,27 @@
"name": "chatgpt-web-service",
"version": "1.0.0",
"private": false,
"description": "ChatGPT Web Bot node service",
"description": "ChatGPT Web Service",
"author": "ChenZhaoYu <chenzhaoyu1994@gmail.com>",
"keywords": [
"chatgpt-web",
"chatgpt",
"chatbot",
"web",
"vue"
"express"
],
"engines": {
"node": ">=18.0.0"
},
"scripts": {
"start": "esno ./src/index.ts",
"prod": "esno ./build/index.js",
"build": "pnpm clean && tsup",
"clean": "rimraf build",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
},
"dependencies": {
"chatgpt": "^4.2.0",
"chatgpt": "^4.3.2",
"express": "^4.18.2"
},
"devDependencies": {
@@ -28,6 +32,8 @@
"dotenv": "^16.0.3",
"eslint": "^8.34.0",
"esno": "^0.16.3",
"rimraf": "^4.1.2",
"tsup": "^6.6.2",
"typescript": "^4.9.5"
}
}

329
service/pnpm-lock.yaml generated
View File

@@ -4,15 +4,17 @@ specifiers:
'@antfu/eslint-config': ^0.35.2
'@types/express': ^4.17.17
'@types/node': ^18.13.0
chatgpt: ^4.2.0
chatgpt: ^4.3.2
dotenv: ^16.0.3
eslint: ^8.34.0
esno: ^0.16.3
express: ^4.18.2
rimraf: ^4.1.2
tsup: ^6.6.2
typescript: ^4.9.5
dependencies:
chatgpt: 4.2.0
chatgpt: 4.3.2
express: 4.18.2
devDependencies:
@@ -22,6 +24,8 @@ devDependencies:
dotenv: 16.0.3
eslint: 8.34.0
esno: 0.16.3
rimraf: 4.1.2
tsup: 6.6.2_typescript@4.9.5
typescript: 4.9.5
packages:
@@ -689,6 +693,18 @@ packages:
color-convert: 2.0.1
dev: true
/any-promise/1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
dev: true
/anymatch/3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
dev: true
/argparse/2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
@@ -742,6 +758,11 @@ packages:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true
/binary-extensions/2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
dev: true
/body-parser/1.20.1:
resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@@ -795,11 +816,26 @@ packages:
semver: 7.3.8
dev: true
/bundle-require/4.0.1_esbuild@0.17.7:
resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
peerDependencies:
esbuild: '>=0.17'
dependencies:
esbuild: 0.17.7
load-tsconfig: 0.2.3
dev: true
/bytes/3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
dev: false
/cac/6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
dev: true
/call-bind/1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
dependencies:
@@ -840,8 +876,8 @@ packages:
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
dev: true
/chatgpt/4.2.0:
resolution: {integrity: sha512-HYQ65GCa8PGtmmUB+XSAa17/IKTy/EEj8QU9HGU8UAsGBtKZushiozC0JpNcTyG+ivpuwzdduXJyL6ELnqkY4A==}
/chatgpt/4.3.2:
resolution: {integrity: sha512-5+Kh0mdP/pDJTL3kA6C6Dp43EO8T8sILPJbbQwOu3J4dK+n/tYpSXsmG6VZkmitAVOffeTonXTGDJwslc66orw==}
engines: {node: '>=18'}
dependencies:
eventsource-parser: 0.0.5
@@ -852,6 +888,21 @@ packages:
uuid: 9.0.0
dev: false
/chokidar/3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'}
dependencies:
anymatch: 3.1.3
braces: 3.0.2
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.2
dev: true
/ci-info/3.8.0:
resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==}
engines: {node: '>=8'}
@@ -885,6 +936,11 @@ packages:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
dev: true
/commander/4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
dev: true
/concat-map/0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
@@ -1576,6 +1632,21 @@ packages:
engines: {node: '>=12'}
dev: false
/execa/5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
dependencies:
cross-spawn: 7.0.3
get-stream: 6.0.1
human-signals: 2.1.0
is-stream: 2.0.1
merge-stream: 2.0.0
npm-run-path: 4.0.1
onetime: 5.1.2
signal-exit: 3.0.7
strip-final-newline: 2.0.0
dev: true
/express/4.18.2:
resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==}
engines: {node: '>= 0.10.0'}
@@ -1753,6 +1824,11 @@ packages:
has: 1.0.3
has-symbols: 1.0.3
/get-stream/6.0.1:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
engines: {node: '>=10'}
dev: true
/get-symbol-description/1.0.0:
resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
engines: {node: '>= 0.4'}
@@ -1779,6 +1855,17 @@ packages:
is-glob: 4.0.3
dev: true
/glob/7.1.6:
resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==}
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
dev: true
/glob/7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
dependencies:
@@ -1896,6 +1983,11 @@ packages:
toidentifier: 1.0.1
dev: false
/human-signals/2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
dev: true
/iconv-lite/0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@@ -1979,6 +2071,13 @@ packages:
has-bigints: 1.0.2
dev: true
/is-binary-path/2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
dependencies:
binary-extensions: 2.2.0
dev: true
/is-boolean-object/1.1.2:
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
engines: {node: '>= 0.4'}
@@ -2068,6 +2167,11 @@ packages:
call-bind: 1.0.2
dev: true
/is-stream/2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
dev: true
/is-string/1.0.7:
resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
engines: {node: '>= 0.4'}
@@ -2103,6 +2207,11 @@ packages:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
/joycon/3.1.1:
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
engines: {node: '>=10'}
dev: true
/js-sdsl/4.3.0:
resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==}
dev: true
@@ -2176,10 +2285,20 @@ packages:
type-check: 0.4.0
dev: true
/lilconfig/2.0.6:
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
engines: {node: '>=10'}
dev: true
/lines-and-columns/1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
/load-tsconfig/0.2.3:
resolution: {integrity: sha512-iyT2MXws+dc2Wi6o3grCFtGXpeMvHmJqS27sMPGtV2eUu4PeFnG+33I8BlFK1t1NWMjOpcx9bridn5yxLDX2gQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
/local-pkg/0.4.3:
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
engines: {node: '>=14'}
@@ -2203,6 +2322,10 @@ packages:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
/lodash.sortby/4.7.0:
resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
dev: true
/lodash/4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: true
@@ -2239,6 +2362,10 @@ packages:
resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
dev: false
/merge-stream/2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
dev: true
/merge2/1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -2284,6 +2411,11 @@ packages:
hasBin: true
dev: false
/mimic-fn/2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
dev: true
/min-indent/1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
@@ -2310,6 +2442,14 @@ packages:
/ms/2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
/mz/2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
dependencies:
any-promise: 1.3.0
object-assign: 4.1.1
thenify-all: 1.6.0
dev: true
/natural-compare-lite/1.4.0:
resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
dev: true
@@ -2332,12 +2472,29 @@ packages:
validate-npm-package-license: 3.0.4
dev: true
/normalize-path/3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
dev: true
/npm-run-path/4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
dependencies:
path-key: 3.1.1
dev: true
/nth-check/2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
dependencies:
boolbase: 1.0.0
dev: true
/object-assign/4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
dev: true
/object-inspect/1.12.3:
resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
@@ -2378,6 +2535,13 @@ packages:
wrappy: 1.0.2
dev: true
/onetime/5.1.2:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
engines: {node: '>=6'}
dependencies:
mimic-fn: 2.1.0
dev: true
/optionator/0.9.1:
resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
engines: {node: '>= 0.8.0'}
@@ -2494,11 +2658,32 @@ packages:
engines: {node: '>=8.6'}
dev: true
/pirates/4.0.5:
resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==}
engines: {node: '>= 6'}
dev: true
/pluralize/8.0.0:
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
engines: {node: '>=4'}
dev: true
/postcss-load-config/3.1.4:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
peerDependencies:
postcss: '>=8.0.9'
ts-node: '>=9.0.0'
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
dependencies:
lilconfig: 2.0.6
yaml: 1.10.2
dev: true
/postcss-selector-parser/6.0.11:
resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==}
engines: {node: '>=4'}
@@ -2575,6 +2760,13 @@ packages:
type-fest: 0.6.0
dev: true
/readdirp/3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
dependencies:
picomatch: 2.3.1
dev: true
/regexp-tree/0.1.24:
resolution: {integrity: sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==}
hasBin: true
@@ -2606,6 +2798,11 @@ packages:
engines: {node: '>=4'}
dev: true
/resolve-from/5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
dev: true
/resolve/1.22.1:
resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
hasBin: true
@@ -2627,6 +2824,20 @@ packages:
glob: 7.2.3
dev: true
/rimraf/4.1.2:
resolution: {integrity: sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==}
engines: {node: '>=14'}
hasBin: true
dev: true
/rollup/3.15.0:
resolution: {integrity: sha512-F9hrCAhnp5/zx/7HYmftvsNBkMfLfk/dXUh73hPSM2E3CRgap65orDNJbLetoiUFwSAk6iHPLvBrZ5iHYvzqsg==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.2
dev: true
/run-parallel/1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
dependencies:
@@ -2729,6 +2940,10 @@ packages:
get-intrinsic: 1.2.0
object-inspect: 1.12.3
/signal-exit/3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true
/slash/3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
@@ -2746,6 +2961,13 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/source-map/0.8.0-beta.0:
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
engines: {node: '>= 8'}
dependencies:
whatwg-url: 7.1.0
dev: true
/spdx-correct/3.1.1:
resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==}
dependencies:
@@ -2801,6 +3023,11 @@ packages:
engines: {node: '>=4'}
dev: true
/strip-final-newline/2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
dev: true
/strip-indent/3.0.0:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'}
@@ -2813,6 +3040,19 @@ packages:
engines: {node: '>=8'}
dev: true
/sucrase/3.29.0:
resolution: {integrity: sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==}
engines: {node: '>=8'}
hasBin: true
dependencies:
commander: 4.1.1
glob: 7.1.6
lines-and-columns: 1.2.4
mz: 2.7.0
pirates: 4.0.5
ts-interface-checker: 0.1.13
dev: true
/supports-color/5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
@@ -2836,6 +3076,19 @@ packages:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
/thenify-all/1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
dependencies:
thenify: 3.3.1
dev: true
/thenify/3.3.1:
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
dependencies:
any-promise: 1.3.0
dev: true
/to-regex-range/5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -2848,6 +3101,21 @@ packages:
engines: {node: '>=0.6'}
dev: false
/tr46/1.0.1:
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
dependencies:
punycode: 2.3.0
dev: true
/tree-kill/1.2.2:
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true
dev: true
/ts-interface-checker/0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
dev: true
/tsconfig-paths/3.14.1:
resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==}
dependencies:
@@ -2861,6 +3129,42 @@ packages:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: true
/tsup/6.6.2_typescript@4.9.5:
resolution: {integrity: sha512-+yQ6SI4rVtp1+YpcYOePumJLEVQ896CDNRt9dJ2L/DeMnLf1+FTOCVw5eioLBH0xLdHgogO9NQ6vPNF5MfkSJw==}
engines: {node: '>=14'}
hasBin: true
peerDependencies:
'@swc/core': ^1
postcss: ^8.4.12
typescript: ^4.1.0
peerDependenciesMeta:
'@swc/core':
optional: true
postcss:
optional: true
typescript:
optional: true
dependencies:
bundle-require: 4.0.1_esbuild@0.17.7
cac: 6.7.14
chokidar: 3.5.3
debug: 4.3.4
esbuild: 0.17.7
execa: 5.1.1
globby: 11.1.0
joycon: 3.1.1
postcss-load-config: 3.1.4
resolve-from: 5.0.0
rollup: 3.15.0
source-map: 0.8.0-beta.0
sucrase: 3.29.0
tree-kill: 1.2.2
typescript: 4.9.5
transitivePeerDependencies:
- supports-color
- ts-node
dev: true
/tsutils/3.21.0_typescript@4.9.5:
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
engines: {node: '>= 6'}
@@ -2996,6 +3300,18 @@ packages:
- supports-color
dev: true
/webidl-conversions/4.0.2:
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
dev: true
/whatwg-url/7.1.0:
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
dependencies:
lodash.sortby: 4.7.0
tr46: 1.0.1
webidl-conversions: 4.0.2
dev: true
/which-boxed-primitive/1.0.2:
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
dependencies:
@@ -3053,6 +3369,11 @@ packages:
yaml: 2.2.1
dev: true
/yaml/1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
dev: true
/yaml/2.2.1:
resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==}
engines: {node: '>= 14'}

View File

@@ -15,67 +15,31 @@ const apiKey = process.env.OPENAI_API_KEY
if (apiKey === undefined)
throw new Error('OPENAI_API_KEY is not defined')
const chatContext = new Set<ChatContext>()
/**
* More Info: https://github.com/transitive-bullshit/chatgpt-api
*/
const api = new ChatGPTAPI({ apiKey })
const api = new ChatGPTAPI({ apiKey, debug: false })
async function chatReply(message: string) {
async function chatReply(
message: string,
lastContext?: { conversationId?: string; parentMessageId?: string },
) {
if (!message)
return sendResponse({ type: 'Fail', message: 'Message is empty' })
try {
// Get the last context from the chat context
let options: SendMessageOptions = {}
const lastContext = Array.from(chatContext).pop()
if (lastContext)
options = { ...lastContext }
const response = await api.sendMessage(message, { ...options })
const { conversationId, id } = response
// Add the new context to the chat context
if (conversationId && id)
chatContext.add({ conversationId, parentMessageId: id })
return sendResponse({ type: 'Success', data: response })
}
catch (error: any) {
global.console.log(error)
return sendResponse({ type: 'Fail', message: error.message })
}
}
async function chatReplayOne(message: string, options?: ChatContext) {
if (!message)
return sendResponse({ type: 'Fail', message: 'Message is empty' })
try {
let messageOptions: SendMessageOptions = {}
if (options) {
const { conversationId, parentMessageId } = options
messageOptions = { conversationId, parentMessageId }
const response = await api.sendMessage(message, { ...messageOptions })
return sendResponse({ type: 'Success', data: response })
}
}
catch (error: any) {
return sendResponse({ type: 'Fail', message: error.message })
}
}
async function clearChatContext() {
// Clear the chat context
chatContext.clear()
return sendResponse({ type: 'Success', message: 'Chat context cleared' })
}
export { chatReply, chatReplayOne, clearChatContext }
export { chatReply }

View File

@@ -1,35 +1,22 @@
import express from 'express'
import type { ChatContext } from './chatgpt'
import { chatReplayOne, chatReply, clearChatContext } from './chatgpt'
import { chatReply } from './chatgpt'
const app = express()
app.use(express.json())
app.all('*', (req, res, next) => {
app.all('*', (_, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Content-Type')
res.header('Access-Control-Allow-Methods', '*')
next()
})
app.listen(3002, () => globalThis.console.log('Server is running on port 3002'))
app.post('/chat', async (req, res) => {
try {
const { prompt } = req.body as { prompt: string }
const response = await chatReply(prompt)
res.send(response)
}
catch (error) {
res.send(error)
}
})
app.post('./chatOne', async (req, res) => {
try {
const { prompt, options = {} } = req.body as { prompt: string; options?: ChatContext }
const response = await chatReplayOne(prompt, options)
const response = await chatReply(prompt, options)
res.send(response)
}
catch (error) {
@@ -37,7 +24,4 @@ app.post('./chatOne', async (req, res) => {
}
})
app.post('/clear', async (req, res) => {
const response = await clearChatContext()
res.send(response)
})
app.listen(3002, () => globalThis.console.log('Server is running on port 3002'))

27
service/tsconfig.json Normal file
View File

@@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es2020",
"lib": [
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"baseUrl": ".",
"outDir": "build",
"noEmit": true
},
"exclude": [
"node_modules",
"build"
],
"include": [
"**/*.ts"
]
}

13
service/tsup.config.ts Normal file
View File

@@ -0,0 +1,13 @@
import { defineConfig } from 'tsup'
export default defineConfig({
entry: ['src/index.ts'],
outDir: 'build',
target: 'es2020',
format: ['cjs'],
splitting: false,
sourcemap: true,
minify: false,
shims: true,
dts: false,
})

View File

@@ -1,9 +1,12 @@
import { post } from '@/utils/request'
export function fetchChatAPI<T = any>(prompt: string) {
export function fetchChatAPI<T = any>(
prompt: string,
options?: { conversationId?: string; parentMessageId?: string },
) {
return post<T>({
url: '/chat',
data: { prompt },
data: { prompt, options },
})
}

View File

@@ -1,52 +0,0 @@
<script setup lang='ts'>
import { SvgIcon } from '@/components/common'
interface Props {
text: string
}
interface Emit {
(e: 'click',): void
(e: 'edit',): void
(e: 'delete',): void
}
defineProps<Props>()
const emit = defineEmits<Emit>()
function handleClick(event: Event) {
emit('click')
event.preventDefault()
}
function handleEdit() {
emit('edit')
}
function handleDelete() {
emit('delete')
}
</script>
<template>
<a
class="relative flex items-center gap-3 px-3 py-3 break-all rounded-md cursor-pointer bg-neutral-50 pr-14 hover:bg-neutral-100 group"
@click="handleClick"
>
<span>
<SvgIcon icon="ri:message-3-line" />
</span>
<div class="relative flex-1 overflow-hidden break-all text-ellipsis whitespace-nowrap max-h-5">
<span>{{ text }}</span>
</div>
<div class="absolute z-10 flex visible right-1">
<button class="p-1" @click="handleEdit">
<SvgIcon icon="ri:edit-line" />
</button>
<button class="p-1" @click="handleDelete">
<SvgIcon icon="ri:delete-bin-line" />
</button>
</div>
</a>
</template>

View File

@@ -9,7 +9,7 @@ defineProps<Props>()
<template>
<div class="p-2 mt-2 rounded-md" :class="[reversal ? 'bg-[#d2f9d1]' : 'bg-[#f4f6f8]']">
<span class="leading-relaxed whitespace-pre-wrap" :class="[{ 'text-red-400': error }]">
<span class="leading-relaxed whitespace-pre-wrap" :class="[{ 'text-red-500': error }]">
<slot />
</span>
</div>

View File

@@ -1,4 +1,3 @@
import Message from './Message/index.vue'
import ListItem from './ListItem/index.vue'
export { Message, ListItem }
export { Message }

View File

@@ -1,50 +1,27 @@
<script setup lang='ts'>
import { nextTick, onMounted, ref } from 'vue'
import { computed, nextTick, onMounted, ref } from 'vue'
import { NButton, NInput, useMessage } from 'naive-ui'
import type { ChatOptions, ChatProps } from './types'
import { Message } from './components'
import { Layout } from './layout'
import { clearConversations, fetchChatAPI } from '@/api'
import { fetchChatAPI } from '@/api'
import { HoverButton, SvgIcon } from '@/components/common'
interface ListProps {
dateTime: string
message: string
reversal?: boolean
error?: boolean
}
const scrollRef = ref<HTMLDivElement>()
const ms = useMessage()
const prompt = ref('')
const loading = ref(false)
const list = ref<ListProps[]>([])
onMounted(initChat)
const list = ref<ChatProps[]>([])
const chatList = computed(() => list.value.filter(item => (!item.reversal && !item.error)))
function initChat() {
addMessage('Hi, I am ChatGPT, a chatbot based on GPT-3.', false)
addMessage('Hi, I am ChatGPT, a chatbot based on GPT-3.')
}
async function handleClear() {
try {
const { message } = await clearConversations()
ms.success(message ?? 'Success')
}
catch (error) {
ms.error('Clear failed, please try again later.')
list.value = []
setTimeout(initChat, 100)
}
}
function handleEnter(event: KeyboardEvent) {
if (event.key === 'Enter')
handleSubmit()
}
onMounted(initChat)
async function handleSubmit() {
if (loading.value)
@@ -57,26 +34,51 @@ async function handleSubmit() {
return
}
addMessage(message, true)
addMessage(message, { reversal: true })
prompt.value = ''
let options: ChatOptions = {}
const lastContext = chatList.value[chatList.value.length - 1]?.options
if (lastContext)
options = { ...lastContext }
try {
loading.value = true
const { data } = await fetchChatAPI(message)
addMessage(data?.text ?? '', false)
const { data } = await fetchChatAPI(message, options)
addMessage(data?.text ?? '', { options: { conversationId: data.conversationId, parentMessageId: data.id } })
}
catch (error: any) {
addMessage(`Error: ${error.message ?? 'Request failed, please try again later.'}`, false, true)
addMessage(`Error: ${error.message ?? 'Request failed, please try again later.'}`, { error: true })
}
finally {
loading.value = false
}
}
function addMessage(message: string, reversal = false, error = false) {
list.value.push({ dateTime: new Date().toLocaleString(), message, reversal, error })
function handleEnter(event: KeyboardEvent) {
if (event.key === 'Enter')
handleSubmit()
}
function addMessage(
message: string,
args?: { reversal?: boolean; error?: boolean; options?: ChatOptions },
) {
list.value.push({
dateTime: new Date().toLocaleString(),
message,
reversal: args?.reversal ?? false,
error: args?.error ?? false,
options: args?.options ?? undefined,
})
nextTick(() => scrollRef.value && (scrollRef.value.scrollTop = scrollRef.value.scrollHeight))
}
function handleClear() {
list.value = []
setTimeout(initChat, 100)
}
</script>
<template>
@@ -86,12 +88,8 @@ function addMessage(message: string, reversal = false, error = false) {
<div ref="scrollRef" class="h-full p-4 overflow-hidden overflow-y-auto">
<div>
<Message
v-for="(item, index) of list"
:key="index"
:date-time="item.dateTime"
:message="item.message"
:reversal="item.reversal"
:error="item.error"
v-for="(item, index) of list" :key="index" :date-time="item.dateTime" :message="item.message"
:reversal="item.reversal" :error="item.error"
/>
</div>
</div>

View File

@@ -0,0 +1,12 @@
export interface ChatOptions {
conversationId?: string
parentMessageId?: string
}
export interface ChatProps {
dateTime: string
message: string
reversal?: boolean
error?: boolean
options?: ChatOptions
}

View File

@@ -18,5 +18,5 @@
},
"types": ["vite/client", "node", "naive-ui/volar"]
},
"exclude": ["node_modules", "dist"]
"exclude": ["node_modules", "dist", "service"]
}