mirror of
https://github.com/Yanyutin753/RefreshToV1Api.git
synced 2025-12-20 01:03:02 +08:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d3d939e3c | ||
|
|
fa971cf108 | ||
|
|
10ae0b415c | ||
|
|
b850592a57 | ||
|
|
719e6f83a9 | ||
|
|
c07d1f3268 | ||
|
|
33fb486c82 | ||
|
|
6203fb3535 | ||
|
|
b19586e24a | ||
|
|
9f80493866 | ||
|
|
36eede643d | ||
|
|
6032546b5d | ||
|
|
7328dadefb | ||
|
|
b7e2af8afd | ||
|
|
04c1599756 | ||
|
|
06665924f6 | ||
|
|
6787069afb | ||
|
|
abbdebc24e | ||
|
|
e599e2a0cc | ||
|
|
0c0dd0e8a7 | ||
|
|
5524ad2b11 | ||
|
|
ef27e47f91 | ||
|
|
26539a0d79 | ||
|
|
a3b5ae310c | ||
|
|
c85a228fb9 | ||
|
|
4a7338637d | ||
|
|
d02e2d0eb1 | ||
|
|
ebd3c3974f | ||
|
|
ab88debcf3 | ||
|
|
73b14891dd | ||
|
|
1f50b3d3a9 | ||
|
|
227781a12c | ||
|
|
f06821d54f | ||
|
|
3637133b2e |
1
.github/workflows/ninja-image.yml
vendored
1
.github/workflows/ninja-image.yml
vendored
@@ -42,6 +42,5 @@ jobs:
|
|||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
yangclivia/pandora-to-api:${{ steps.tag_name.outputs.tag }}
|
yangclivia/pandora-to-api:${{ steps.tag_name.outputs.tag }}
|
||||||
yangclivia/pandora-to-api:0.7.7
|
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
build-args: TARGETPLATFORM=${{ matrix.platform }}
|
build-args: TARGETPLATFORM=${{ matrix.platform }}
|
||||||
|
|||||||
46
.github/workflows/xyhelper-deploy.yml
vendored
Normal file
46
.github/workflows/xyhelper-deploy.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: xyhelper Build and Push Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'Tag Name'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Set tag name
|
||||||
|
id: tag_name
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" = "release" ]; then
|
||||||
|
echo "::set-output name=tag::${GITHUB_REF#refs/tags/}"
|
||||||
|
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
echo "::set-output name=tag::${{ github.event.inputs.tag }}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build and push Docker image with Release tag
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
yangclivia/pandora-to-api:${{ steps.tag_name.outputs.tag }}
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
build-args: TARGETPLATFORM=${{ matrix.platform }}
|
||||||
6
.idea/encodings.xml
generated
Normal file
6
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$/log/access.log" charset="GBK" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -10,13 +10,15 @@ COPY . /app
|
|||||||
# 设置环境变量
|
# 设置环境变量
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
RUN chmod +x /app/main.py
|
RUN chmod +x /app/start.sh
|
||||||
|
|
||||||
|
RUN apt update && apt install -y jq
|
||||||
|
|
||||||
# # 设置 pip 源为清华大学镜像
|
# # 设置 pip 源为清华大学镜像
|
||||||
# RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
|
# RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
# 安装任何所需的依赖项
|
# 安装任何所需的依赖项
|
||||||
RUN pip install --no-cache-dir flask flask_apscheduler requests Pillow flask-cors tiktoken fake_useragent redis websocket-client pysocks requests[socks] websocket-client[optional]
|
RUN pip install --no-cache-dir flask flask_apscheduler gunicorn requests Pillow flask-cors tiktoken fake_useragent redis websocket-client pysocks requests[socks] websocket-client[optional]
|
||||||
|
|
||||||
# 在容器启动时运行 Flask 应用
|
# 在容器启动时运行 Flask 应用
|
||||||
CMD ["python3", "main.py"]
|
CMD ["/app/start.sh"]
|
||||||
|
|||||||
74
Readme.md
74
Readme.md
@@ -1,21 +1,29 @@
|
|||||||
## 0.7.7 ninja版本项目简介
|
## 项目简介
|
||||||
[](https://github.com/Yanyutin753/refresh-gpt-chat/stargazers)
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
>
|
>
|
||||||
> Respect Zhile大佬 , Respect Wizerd!
|
> Respect `xyhelper` ,Respect `ninja` , Respect `Wizerd`!
|
||||||
|
|
||||||
感谢pandoraNext和Wizerd的付出,敬礼!!!
|
感谢xyhelper、ninja和Wizerd大佬们的付出,敬礼!!!
|
||||||
|
|
||||||
本项目支持:
|
本项目支持:
|
||||||
|
|
||||||
1. 将 ninja `proxy` 模式下的 `backend-api` 转为 `/v1/chat/completions` 接口,支持流式和非流式响应。
|
1. 将 xyhelper `proxy` 模式下的 `backend-api免费接口` 转为 `/v1/chat/completions` 接口,支持流式和非流式响应。
|
||||||
|
|
||||||
2. 将 ninja `proxy` 模式下的 `backend-api` 转为 `/v1/images/generations` 接口
|
2. 将 xyhelper `proxy` 模式下的 `backend-api免费接口` 转为 `/v1/images/generations` 接口
|
||||||
|
|
||||||
3. 支持直接把refresh_token作为请求key,方便接入one_api
|
3. 支持直接把refresh_token作为请求key,方便接入one_api
|
||||||
|
|
||||||
4. 支持 gpt-4-mobile 、gpt-4-s 、基本所有的GPTS
|
4. 支持 gpt-4-mobile 、gpt-4-s 、基本所有的GPTS
|
||||||
|
|
||||||
|
* **xyhelper 的 免费 backend-api 接口,无需打码**
|
||||||
|
|
||||||
|
* **xyhelper接口每分钟最多请求30次,介意请绕行**
|
||||||
|
* 我是开发者,我想自行修改功能->前往源码库 https://github.com/xyhelper/chatgpt-mirror-server
|
||||||
|
* 我没服务器,也没有官网账号,只想使用->前往官网购买我们运营的会员服务 https://www.xyhelper.com.cn
|
||||||
|
* 我想做商业用途,我想自己运营->老板里面请 https://www.xyhelper.com.cn/access
|
||||||
|
* 我有服务器,我想自己部署->请继续阅读本文档(有条件的话给个star吧)
|
||||||
|
|
||||||
如果本项目对你有帮助的话,请点个小星星吧~
|
如果本项目对你有帮助的话,请点个小星星吧~
|
||||||
|
|
||||||
如果有什么在项目的使用过程中的疑惑或需求,欢迎加入 Community Telegram Channel: [Inker 的魔法世界](https://t.me/InkerWorld) 来和大家一起交流一下~
|
如果有什么在项目的使用过程中的疑惑或需求,欢迎加入 Community Telegram Channel: [Inker 的魔法世界](https://t.me/InkerWorld) 来和大家一起交流一下~
|
||||||
@@ -34,7 +42,7 @@
|
|||||||
|
|
||||||
- [x] 支持 gpt-3.5-turbo
|
- [x] 支持 gpt-3.5-turbo
|
||||||
|
|
||||||
- [x] 支持 动态gpts
|
- [x] 支持 gpts
|
||||||
|
|
||||||
- [x] 支持 流式输出
|
- [x] 支持 流式输出
|
||||||
|
|
||||||
@@ -59,13 +67,13 @@
|
|||||||
## 注意
|
## 注意
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> 1. 本项目的运行需要 ninja
|
> 1. 本项目的运行需要 xyhelper 的免费接口
|
||||||
>
|
>
|
||||||
> 2. 本项目实际为将来自 `/v1/chat/completions` 的请求转发到ninja的 `/backend-api/conversation` 接口,因此本项目并不支持高并发操作,请不要接入如 `沉浸式翻译` 等高并发项目。
|
> 2. 本项目实际为将来自 `/v1/chat/completions` 的请求转发到xyhelper免费接口的 `/backend-api/conversation` 接口,因此本项目并不支持高并发操作,请不要接入如 `沉浸式翻译` 等高并发项目。
|
||||||
>
|
>
|
||||||
> 3. 本项目支持使用apple平台的refresh_token作为请求key.
|
> 3. 本项目支持使用apple平台的refresh_token作为请求key.
|
||||||
>
|
>
|
||||||
> 4. 本项目并不能绕过 OpenAI 和 ninja 官方的限制,只提供便利,不提供绕过。
|
> 4. 本项目并不能绕过 OpenAI 和 xyhelper 官方的限制,只提供便利,不提供绕过。
|
||||||
>
|
>
|
||||||
> 5. 提问的艺术:当出现项目不能正常运行时,请携带 `DEBUG` 级别的日志在 `Issue` 或者社区群内提问,否则将开启算命模式~
|
> 5. 提问的艺术:当出现项目不能正常运行时,请携带 `DEBUG` 级别的日志在 `Issue` 或者社区群内提问,否则将开启算命模式~
|
||||||
|
|
||||||
@@ -91,13 +99,13 @@
|
|||||||
|
|
||||||
- `need_log_to_file`: 用于设置是否需要将日志输出到文件,可选值为:`true`、`false`,默认为 `true`,日志文件路径为:`./log/access.log`,默认每天会自动分割日志文件。
|
- `need_log_to_file`: 用于设置是否需要将日志输出到文件,可选值为:`true`、`false`,默认为 `true`,日志文件路径为:`./log/access.log`,默认每天会自动分割日志文件。
|
||||||
|
|
||||||
- `process_workers`: 用于设置进程数,如果不需要设置,可以保持不变,如果需要设置,可以设置为需要设置的值,如果设置为 `1`,则会强制设置为单进程模式。
|
- `process_workers`: 用于设置进程数,如果不需要设置,可以保持不变,如果需要设置,可以设置为需要设置的值,默认为 `2`。
|
||||||
|
|
||||||
- `process_threads`: 用于设置线程数,如果不需要设置,可以保持不变,如果需要设置,可以设置为需要设置的值,如果设置为 `1`,则会强制设置为单线程模式。
|
- `process_threads`: 用于设置线程数,如果不需要设置,可以保持不变,如果需要设置,可以设置为需要设置的值,默认为 `2`。
|
||||||
|
|
||||||
- `upstream_base_url`: ninja 的部署地址,如:`https://pandoranext.com`,注意:不要以 `/` 结尾。可以填写为本项目可以访问到的 PandoraNext 的内网地址。
|
- `upstream_base_url`: xyhelper 的免费接口地址,如:`https://demo.xyhelper.cn`,注意:不要以 `/` 结尾。
|
||||||
|
|
||||||
- `upstream_api_prefix`: PandoraNext Proxy 模式下的 API 前缀
|
- `upstream_api_prefix`: 默认为""
|
||||||
|
|
||||||
- `backend_container_url`: 用于dalle模型生成图片的时候展示所用,需要设置为使用如 [ChatGPT-Next-Web](https://github.com/ChatGPTNextWebTeam/ChatGPT-Next-Web) 的用户可以访问到的本项目地址,如:`http://1.2.3.4:50011`,同原环境变量中的 `UPLOAD_BASE_URL`
|
- `backend_container_url`: 用于dalle模型生成图片的时候展示所用,需要设置为使用如 [ChatGPT-Next-Web](https://github.com/ChatGPTNextWebTeam/ChatGPT-Next-Web) 的用户可以访问到的本项目地址,如:`http://1.2.3.4:50011`,同原环境变量中的 `UPLOAD_BASE_URL`
|
||||||
|
|
||||||
@@ -143,7 +151,8 @@ PS. 注意,arkose_urls中的地址需要支持PandoraNext的Arkose Token获取
|
|||||||
|
|
||||||
- `enableOai`:用于设置是否使用官网通过refresh_token刷新access_token,仅在 `enableOai` 为 `true` 时生效。
|
- `enableOai`:用于设置是否使用官网通过refresh_token刷新access_token,仅在 `enableOai` 为 `true` 时生效。
|
||||||
|
|
||||||
- `ninja_refreshToAccess_Url`:用于设置使用ninja来进行使用refresh_token刷新access_token,enableOai为false的时候必填。
|
- `xyhelper_refreshToAccess_Url`:用于设置使用xyhelper来进行使用refresh_token刷新access_token,enableOai为false的时候必填
|
||||||
|
- 默认为"https://demo.xyhelper.cn/applelogin"
|
||||||
|
|
||||||
- `redis`
|
- `redis`
|
||||||
|
|
||||||
@@ -157,9 +166,7 @@ PS. 注意,arkose_urls中的地址需要支持PandoraNext的Arkose Token获取
|
|||||||
|
|
||||||
## GPTS配置说明
|
## GPTS配置说明
|
||||||
|
|
||||||
### 使用 GPTS
|
如果需要使用 GPTS,需要修改 `gpts.json` 文件,其中每个对象的key即为调用对应 GPTS 的时候使用的模型名称,而 `id` 则为对应的模型id,该 `id` 对应每个 GPTS 的链接的后缀。配置多个GPTS的时候用逗号隔开。
|
||||||
|
|
||||||
1. 可修改 `gpts.json` 文件,其中每个对象的key即为调用对应 GPTS 的时候使用的模型名称,而 `id` 则为对应的模型id,该 `id` 对应每个 GPTS 的链接的后缀。配置多个GPTS的时候用逗号隔开。
|
|
||||||
|
|
||||||
例如:PandoraNext的官方 GPTS 的链接为:`https://chat.oaifree.com/g/g-CFsXuTRfy-pandoranextzhu-shou`,则该模型的 `id` 的值应为 `g-CFsXuTRfy-pandoranextzhu-shou`,而模型名可以自定义。
|
例如:PandoraNext的官方 GPTS 的链接为:`https://chat.oaifree.com/g/g-CFsXuTRfy-pandoranextzhu-shou`,则该模型的 `id` 的值应为 `g-CFsXuTRfy-pandoranextzhu-shou`,而模型名可以自定义。
|
||||||
|
|
||||||
@@ -176,16 +183,7 @@ PS. 注意,arkose_urls中的地址需要支持PandoraNext的Arkose Token获取
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
2. 直接请求的时候加上相应的gpt-4-gizmo-XXX
|
注意:使用该配置的时候需要保证正确填写 `docker-compose.yml` 的环境变量 `KEY_FOR_GPTS_INFO`,同时该变量设置的 `key` 允许访问所有配置的 GPTS。
|
||||||
```json
|
|
||||||
{
|
|
||||||
"stream":true,
|
|
||||||
"model":"gpt-4-gizmo-XXXX",
|
|
||||||
"messages": [{"role": "user", "content": "你是什么模型"}]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
注意:使用该配置的时候需要保证正确填写 `config.json` 文件的环境变量 `KEY_FOR_GPTS_INFO`,同时该变量设置的 `key` 允许访问所有配置的 GPTS。
|
|
||||||
|
|
||||||
## 绘图接口使用说明
|
## 绘图接口使用说明
|
||||||
|
|
||||||
@@ -193,7 +191,7 @@ PS. 注意,arkose_urls中的地址需要支持PandoraNext的Arkose Token获取
|
|||||||
|
|
||||||
请求方式:`POST`
|
请求方式:`POST`
|
||||||
|
|
||||||
请求头:正常携带 `Authorization` 和 `Content-Type` 即可,`Authorization` 的值为 `Bearer <ninja 的 fk>`,`Content-Type` 的值为 `application/json`
|
请求头:正常携带 `Authorization` 和 `Content-Type` 即可,`Authorization` 的值为 `Bearer <refresh_token>`,`Content-Type` 的值为 `application/json`
|
||||||
|
|
||||||
请求体格式示例:
|
请求体格式示例:
|
||||||
|
|
||||||
@@ -326,20 +324,19 @@ PS. 注意,arkose_urls中的地址需要支持PandoraNext的Arkose Token获取
|
|||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
|
|
||||||
以[ChatGPT-Next-Web](https://github.com/Yanyutin753/ChatGPT-Next-Web-LangChain-Gpt-4-All)项目插件版的docker-compose部署为例,支持完全适配项目,这里提供一个简单的部署配置文件示例:
|
以ChatGPT-Next-Web项目的docker-compose部署为例,这里提供一个简单的部署配置文件示例:
|
||||||
|
|
||||||
```
|
```
|
||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
chatgpt-next-web:
|
chatgpt-next-web:
|
||||||
image: yangclivia/chatgpt-next-web-langchain
|
image: yidadaa/chatgpt-next-web
|
||||||
ports:
|
ports:
|
||||||
- "50013:3000"
|
- "50013:3000"
|
||||||
environment:
|
environment:
|
||||||
- CUSTOM_MODELS=-all,+gpt-3.5-turbo,+gpt-4-s,+gpt-4-mobile,+gpt-4-vision-preview,+gpt-4-gizmo-XXX
|
|
||||||
- OPENAI_API_KEY=<正确的refresh_token>
|
- OPENAI_API_KEY=<正确的refresh_token>
|
||||||
- BASE_URL=<backend-to-api容器地址>
|
- BASE_URL=<backend-to-api容器地址>
|
||||||
- CUSTOM_MODELS=-gpt-4-0613,-gpt-4-32k,-gpt-4-32k-0613,-gpt-4-turbo-preview,-gpt-4-1106-preview,-gpt-4-0125-preview,-gpt-3.5-turbo-0125,-gpt-3.5-turbo-0613,-gpt-3.5-turbo-1106,-gpt-3.5-turbo-16k,-gpt-3.5-turbo-16k-0613,+gpt-3.5-turbo,+gpt-4,+gpt-4-mobile,+gpt-4-vision-preview,+gpt-4-mobile,+<gpts.json 中的模型名>
|
- CUSTOM_MODELS=+gpt-4-s,+gpt-4-mobile,+<gpts.json 中的模型名>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -354,20 +351,17 @@ services:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 读文件
|
|
||||||

|
|
||||||
|
|
||||||
### 绘图
|
### 绘图
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### GPT-4-Mobile
|
### GPT-4-Mobile
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### GPTS
|
### GPTS
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Bot 模式
|
### Bot 模式
|
||||||
|
|
||||||
@@ -394,4 +388,4 @@ services:
|
|||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
[](https://star-history.com/#Yanyutin753/ninjaToV1Api_refresh&Date)
|
[](https://star-history.com/#Yanyutin753/xyhelperV1Api_refresh&Date)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"process_workers": 2,
|
"process_workers": 2,
|
||||||
"process_threads": 2,
|
"process_threads": 2,
|
||||||
"proxy": "",
|
"proxy": "",
|
||||||
"upstream_base_url": "",
|
"upstream_base_url": "https://demo.xyhelper.cn",
|
||||||
"upstream_api_prefix": "",
|
"upstream_api_prefix": "",
|
||||||
"backend_container_url": "",
|
"backend_container_url": "",
|
||||||
"backend_container_api_prefix": "",
|
"backend_container_api_prefix": "",
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
},
|
},
|
||||||
"refresh_ToAccess": {
|
"refresh_ToAccess": {
|
||||||
"stream_sleep_time": 0,
|
"stream_sleep_time": 0,
|
||||||
"enableOai":"true",
|
"enableOai":"false",
|
||||||
"ninja_refreshToAccess_Url": ""
|
"xyhelper_refreshToAccess_Url": "https://demo.xyhelper.cn/applelogin"
|
||||||
},
|
},
|
||||||
"redis": {
|
"redis": {
|
||||||
"host": "redis",
|
"host": "redis",
|
||||||
|
|||||||
@@ -1,5 +1 @@
|
|||||||
{
|
{}
|
||||||
"gpt-4-classic": {
|
|
||||||
"id":"g-YyyyMT9XH-chatgpt-classic"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@ version: '3'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
backend-to-api:
|
backend-to-api:
|
||||||
image: yangclivia/pandora-to-api:0.7.7
|
image: yangclivia/pandora-to-api:0.7.8
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "50011:33333"
|
- "50011:33333"
|
||||||
|
|||||||
1162
log/access.log
Normal file
1162
log/access.log
Normal file
File diff suppressed because it is too large
Load Diff
152
main.py
152
main.py
@@ -62,10 +62,10 @@ BOT_MODE_ENABLED_CODE_BLOCK_OUTPUT = BOT_MODE.get('enabled_plugin_output', 'fals
|
|||||||
|
|
||||||
BOT_MODE_ENABLED_PLAIN_IMAGE_URL_OUTPUT = BOT_MODE.get('enabled_plain_image_url_output', 'false').lower() == 'true'
|
BOT_MODE_ENABLED_PLAIN_IMAGE_URL_OUTPUT = BOT_MODE.get('enabled_plain_image_url_output', 'false').lower() == 'true'
|
||||||
|
|
||||||
# ninjaToV1Api_refresh
|
# xyhelperToV1Api_refresh
|
||||||
REFRESH_TOACCESS = CONFIG.get('refresh_ToAccess', {})
|
REFRESH_TOACCESS = CONFIG.get('refresh_ToAccess', {})
|
||||||
REFRESH_TOACCESS_ENABLEOAI = REFRESH_TOACCESS.get('enableOai', 'true').lower() == 'true'
|
REFRESH_TOACCESS_ENABLEOAI = REFRESH_TOACCESS.get('enableOai', 'true').lower() == 'true'
|
||||||
REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL = REFRESH_TOACCESS.get('ninja_refreshToAccess_Url', '')
|
REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL = REFRESH_TOACCESS.get('xyhelper_refreshToAccess_Url', '')
|
||||||
STEAM_SLEEP_TIME = REFRESH_TOACCESS.get('steam_sleep_time', 0)
|
STEAM_SLEEP_TIME = REFRESH_TOACCESS.get('steam_sleep_time', 0)
|
||||||
|
|
||||||
NEED_DELETE_CONVERSATION_AFTER_RESPONSE = CONFIG.get('need_delete_conversation_after_response',
|
NEED_DELETE_CONVERSATION_AFTER_RESPONSE = CONFIG.get('need_delete_conversation_after_response',
|
||||||
@@ -198,12 +198,15 @@ def oaiGetAccessToken(refresh_token):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# ninja获得access_token
|
# xyhelper获得access_token
|
||||||
def ninjaGetAccessToken(getAccessTokenUrl, refresh_token):
|
def xyhelperGetAccessToken(getAccessTokenUrl, refresh_token):
|
||||||
try:
|
try:
|
||||||
logger.info("将通过这个网址请求access_token:" + getAccessTokenUrl)
|
logger.info("将通过这个网址请求access_token:" + getAccessTokenUrl)
|
||||||
headers = {"Authorization": "Bearer " + refresh_token}
|
|
||||||
response = requests.post(getAccessTokenUrl, headers=headers)
|
data = {
|
||||||
|
'refresh_token': refresh_token,
|
||||||
|
}
|
||||||
|
response = requests.post(getAccessTokenUrl, data=data)
|
||||||
if not response.ok:
|
if not response.ok:
|
||||||
logger.error("Request 失败: " + response.text.strip())
|
logger.error("Request 失败: " + response.text.strip())
|
||||||
return None
|
return None
|
||||||
@@ -227,7 +230,7 @@ def updateGptsKey():
|
|||||||
if REFRESH_TOACCESS_ENABLEOAI:
|
if REFRESH_TOACCESS_ENABLEOAI:
|
||||||
access_token = oaiGetAccessToken(KEY_FOR_GPTS_INFO)
|
access_token = oaiGetAccessToken(KEY_FOR_GPTS_INFO)
|
||||||
else:
|
else:
|
||||||
access_token = ninjaGetAccessToken(REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL, KEY_FOR_GPTS_INFO)
|
access_token = xyhelperGetAccessToken(REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL, KEY_FOR_GPTS_INFO)
|
||||||
if access_token.startswith("eyJhb"):
|
if access_token.startswith("eyJhb"):
|
||||||
KEY_FOR_GPTS_INFO_ACCESS_TOKEN = access_token
|
KEY_FOR_GPTS_INFO_ACCESS_TOKEN = access_token
|
||||||
logging.info("KEY_FOR_GPTS_INFO_ACCESS_TOKEN被更新:" + KEY_FOR_GPTS_INFO_ACCESS_TOKEN)
|
logging.info("KEY_FOR_GPTS_INFO_ACCESS_TOKEN被更新:" + KEY_FOR_GPTS_INFO_ACCESS_TOKEN)
|
||||||
@@ -252,7 +255,7 @@ def fetch_gizmo_info(base_url, proxy_api_prefix, model_id):
|
|||||||
# 将配置添加到全局列表
|
# 将配置添加到全局列表
|
||||||
def add_config_to_global_list(base_url, proxy_api_prefix, gpts_data):
|
def add_config_to_global_list(base_url, proxy_api_prefix, gpts_data):
|
||||||
global gpts_configurations
|
global gpts_configurations
|
||||||
updateGptsKey()
|
updateGptsKey() # cSpell:ignore Gpts
|
||||||
# print(f"gpts_data: {gpts_data}")
|
# print(f"gpts_data: {gpts_data}")
|
||||||
for model_name, model_info in gpts_data.items():
|
for model_name, model_info in gpts_data.items():
|
||||||
# print(f"model_name: {model_name}")
|
# print(f"model_name: {model_name}")
|
||||||
@@ -273,17 +276,15 @@ def add_config_to_global_list(base_url, proxy_api_prefix, gpts_data):
|
|||||||
if gizmo_info:
|
if gizmo_info:
|
||||||
redis_client.set(model_id, str(gizmo_info))
|
redis_client.set(model_id, str(gizmo_info))
|
||||||
logger.info(f"Cached gizmo info for {model_name}, {model_id}")
|
logger.info(f"Cached gizmo info for {model_name}, {model_id}")
|
||||||
|
# 检查模型名称是否已经在列表中
|
||||||
# 检查模型名称是否已经在列表中
|
if not any(d['name'] == model_name for d in gpts_configurations):
|
||||||
if gizmo_info and not any(d['name'] == model_name for d in gpts_configurations):
|
gpts_configurations.append({
|
||||||
gpts_configurations.append({
|
'name': model_name,
|
||||||
'name': model_name,
|
'id': model_id,
|
||||||
'id': model_id,
|
'config': gizmo_info
|
||||||
'config': gizmo_info
|
})
|
||||||
})
|
else:
|
||||||
else:
|
logger.info(f"Model already exists in the list, skipping...")
|
||||||
logger.info(f"Model already exists in the list, skipping...")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def generate_gpts_payload(model, messages):
|
def generate_gpts_payload(model, messages):
|
||||||
@@ -321,9 +322,9 @@ scheduler.start()
|
|||||||
# PANDORA_UPLOAD_URL = 'files.pandoranext.com'
|
# PANDORA_UPLOAD_URL = 'files.pandoranext.com'
|
||||||
|
|
||||||
|
|
||||||
VERSION = '0.7.7.3'
|
VERSION = '0.7.8.1'
|
||||||
# VERSION = 'test'
|
# VERSION = 'test'
|
||||||
UPDATE_INFO = 'flask直接启动,解决部分机cpu占用过大问题'
|
UPDATE_INFO = '支持gpt-4-gizmo-XXX,动态配置GPTS'
|
||||||
# UPDATE_INFO = '【仅供临时测试使用】 '
|
# UPDATE_INFO = '【仅供临时测试使用】 '
|
||||||
|
|
||||||
# 解析响应中的信息
|
# 解析响应中的信息
|
||||||
@@ -402,7 +403,7 @@ with app.app_context():
|
|||||||
|
|
||||||
logger.info(f"REFRESH_TOACCESS_ENABLEOAI: {REFRESH_TOACCESS_ENABLEOAI}")
|
logger.info(f"REFRESH_TOACCESS_ENABLEOAI: {REFRESH_TOACCESS_ENABLEOAI}")
|
||||||
if not REFRESH_TOACCESS_ENABLEOAI:
|
if not REFRESH_TOACCESS_ENABLEOAI:
|
||||||
logger.info(f"REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL: {REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL}")
|
logger.info(f"REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL: {REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL}")
|
||||||
|
|
||||||
if BOT_MODE_ENABLED:
|
if BOT_MODE_ENABLED:
|
||||||
logger.info(f"enabled_markdown_image_output: {BOT_MODE_ENABLED_MARKDOWN_IMAGE_OUTPUT}")
|
logger.info(f"enabled_markdown_image_output: {BOT_MODE_ENABLED_MARKDOWN_IMAGE_OUTPUT}")
|
||||||
@@ -410,10 +411,10 @@ with app.app_context():
|
|||||||
logger.info(f"enabled_bing_reference_output: {BOT_MODE_ENABLED_BING_REFERENCE_OUTPUT}")
|
logger.info(f"enabled_bing_reference_output: {BOT_MODE_ENABLED_BING_REFERENCE_OUTPUT}")
|
||||||
logger.info(f"enabled_plugin_output: {BOT_MODE_ENABLED_CODE_BLOCK_OUTPUT}")
|
logger.info(f"enabled_plugin_output: {BOT_MODE_ENABLED_CODE_BLOCK_OUTPUT}")
|
||||||
|
|
||||||
# ninjaToV1Api_refresh
|
# xyhelperToV1Api_refresh
|
||||||
|
|
||||||
logger.info(f"REFRESH_TOACCESS_ENABLEOAI: {REFRESH_TOACCESS_ENABLEOAI}")
|
logger.info(f"REFRESH_TOACCESS_ENABLEOAI: {REFRESH_TOACCESS_ENABLEOAI}")
|
||||||
logger.info(f"REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL: {REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL}")
|
logger.info(f"REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL: {REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL}")
|
||||||
logger.info(f"STEAM_SLEEP_TIME: {STEAM_SLEEP_TIME}")
|
logger.info(f"STEAM_SLEEP_TIME: {STEAM_SLEEP_TIME}")
|
||||||
|
|
||||||
if not BASE_URL:
|
if not BASE_URL:
|
||||||
@@ -867,8 +868,8 @@ def send_text_prompt_and_get_response(messages, api_key, stream, model):
|
|||||||
ori_model_name = model_config.get('ori_name', model)
|
ori_model_name = model_config.get('ori_name', model)
|
||||||
logger.info(f"原模型名: {ori_model_name}")
|
logger.info(f"原模型名: {ori_model_name}")
|
||||||
else:
|
else:
|
||||||
logger.info(f"请求模型名: {model}")
|
|
||||||
ori_model_name = model
|
ori_model_name = model
|
||||||
|
logger.info(f"请求模型名: {model}")
|
||||||
if ori_model_name == 'gpt-4-s':
|
if ori_model_name == 'gpt-4-s':
|
||||||
payload = {
|
payload = {
|
||||||
# 构建 payload
|
# 构建 payload
|
||||||
@@ -944,28 +945,8 @@ def send_text_prompt_and_get_response(messages, api_key, stream, model):
|
|||||||
logger.info(f"Model already exists in the list, skipping...")
|
logger.info(f"Model already exists in the list, skipping...")
|
||||||
payload = generate_gpts_payload(model, formatted_messages)
|
payload = generate_gpts_payload(model, formatted_messages)
|
||||||
else:
|
else:
|
||||||
payload = {
|
raise Exception('KEY_FOR_GPTS_INFO is not accessible')
|
||||||
# 构建 payload
|
|
||||||
"action": "next",
|
|
||||||
"messages": formatted_messages,
|
|
||||||
"parent_message_id": str(uuid.uuid4()),
|
|
||||||
"model": "text-davinci-002-render-sha",
|
|
||||||
"timezone_offset_min": -480,
|
|
||||||
"suggestions": [
|
|
||||||
"What are 5 creative things I could do with my kids' art? I don't want to throw them away, but it's also so much clutter.",
|
|
||||||
"I want to cheer up my friend who's having a rough day. Can you suggest a couple short and sweet text messages to go with a kitten gif?",
|
|
||||||
"Come up with 5 concepts for a retro-style arcade game.",
|
|
||||||
"I have a photoshoot tomorrow. Can you recommend me some colors and outfit options that will look good on camera?"
|
|
||||||
],
|
|
||||||
"history_and_training_disabled": False,
|
|
||||||
"arkose_token": None,
|
|
||||||
"conversation_mode": {
|
|
||||||
"kind": "primary_assistant"
|
|
||||||
},
|
|
||||||
"force_paragen": False,
|
|
||||||
"force_rate_limit": False
|
|
||||||
}
|
|
||||||
logger.debug('KEY_FOR_GPTS_INFO is not accessible')
|
|
||||||
else:
|
else:
|
||||||
payload = generate_gpts_payload(model, formatted_messages)
|
payload = generate_gpts_payload(model, formatted_messages)
|
||||||
if not payload:
|
if not payload:
|
||||||
@@ -1209,7 +1190,7 @@ def generate_actions_allow_payload(author_role, author_name, target_message_id,
|
|||||||
"action": "next",
|
"action": "next",
|
||||||
"messages": [
|
"messages": [
|
||||||
{
|
{
|
||||||
"id": str(uuid.uuid4()),
|
"id": generate_custom_uuid_v4(),
|
||||||
"author": {
|
"author": {
|
||||||
"role": author_role,
|
"role": author_role,
|
||||||
"name": author_name
|
"name": author_name
|
||||||
@@ -2060,7 +2041,7 @@ def old_data_fetcher(upstream_response, data_queue, stop_event, last_data_time,
|
|||||||
"id": chat_message_id,
|
"id": chat_message_id,
|
||||||
"object": "chat.completion.chunk",
|
"object": "chat.completion.chunk",
|
||||||
"created": timestamp,
|
"created": timestamp,
|
||||||
"model": model,
|
"model": message.get("metadata", {}).get("model_slug"),
|
||||||
"choices": [
|
"choices": [
|
||||||
{
|
{
|
||||||
"index": 0,
|
"index": 0,
|
||||||
@@ -2314,7 +2295,7 @@ def chat_completions():
|
|||||||
if REFRESH_TOACCESS_ENABLEOAI:
|
if REFRESH_TOACCESS_ENABLEOAI:
|
||||||
api_key = oaiGetAccessToken(api_key)
|
api_key = oaiGetAccessToken(api_key)
|
||||||
else:
|
else:
|
||||||
api_key = ninjaGetAccessToken(REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL, api_key)
|
api_key = xyhelperGetAccessToken(REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL, api_key)
|
||||||
if not api_key.startswith("eyJhb"):
|
if not api_key.startswith("eyJhb"):
|
||||||
return jsonify({"error": "refresh_token is wrong or refresh_token url is wrong!"}), 401
|
return jsonify({"error": "refresh_token is wrong or refresh_token url is wrong!"}), 401
|
||||||
add_to_dict(refresh_token, api_key)
|
add_to_dict(refresh_token, api_key)
|
||||||
@@ -2416,32 +2397,36 @@ def chat_completions():
|
|||||||
ori_model_name = model_config.get('ori_name', model)
|
ori_model_name = model_config.get('ori_name', model)
|
||||||
input_tokens = count_total_input_words(messages, ori_model_name)
|
input_tokens = count_total_input_words(messages, ori_model_name)
|
||||||
comp_tokens = count_tokens(all_new_text, ori_model_name)
|
comp_tokens = count_tokens(all_new_text, ori_model_name)
|
||||||
response_json = {
|
if input_tokens >= 100 and comp_tokens <= 0:
|
||||||
"id": generate_unique_id("chatcmpl"),
|
# 返回错误消息和状态码429
|
||||||
"object": "chat.completion",
|
error_response = {"error": "空回复"}
|
||||||
"created": int(time.time()), # 使用当前时间戳
|
return jsonify(error_response), 429
|
||||||
"model": model, # 使用请求中指定的模型
|
else:
|
||||||
"choices": [
|
response_json = {
|
||||||
{
|
"id": generate_unique_id("chatcmpl"),
|
||||||
"index": 0,
|
"object": "chat.completion",
|
||||||
"message": {
|
"created": int(time.time()), # 使用当前时间戳
|
||||||
"role": "assistant",
|
"model": model, # 使用请求中指定的模型
|
||||||
"content": all_new_text # 使用累积的文本
|
"choices": [
|
||||||
},
|
{
|
||||||
"finish_reason": "stop"
|
"index": 0,
|
||||||
}
|
"message": {
|
||||||
],
|
"role": "assistant",
|
||||||
"usage": {
|
"content": all_new_text # 使用累积的文本
|
||||||
# 这里的 token 计数需要根据实际情况计算
|
},
|
||||||
"prompt_tokens": input_tokens,
|
"finish_reason": "stop"
|
||||||
"completion_tokens": comp_tokens,
|
}
|
||||||
"total_tokens": input_tokens + comp_tokens
|
],
|
||||||
},
|
"usage": {
|
||||||
"system_fingerprint": None
|
# 这里的 token 计数需要根据实际情况计算
|
||||||
}
|
"prompt_tokens": input_tokens,
|
||||||
|
"completion_tokens": comp_tokens,
|
||||||
# 返回 JSON 响应
|
"total_tokens": input_tokens + comp_tokens
|
||||||
return jsonify(response_json)
|
},
|
||||||
|
"system_fingerprint": None
|
||||||
|
}
|
||||||
|
# 返回 JSON 响应
|
||||||
|
return jsonify(response_json)
|
||||||
else:
|
else:
|
||||||
return Response(generate(), mimetype='text/event-stream')
|
return Response(generate(), mimetype='text/event-stream')
|
||||||
|
|
||||||
@@ -2479,7 +2464,7 @@ def images_generations():
|
|||||||
refresh_token = api_key
|
refresh_token = api_key
|
||||||
api_key = oaiGetAccessToken(api_key)
|
api_key = oaiGetAccessToken(api_key)
|
||||||
else:
|
else:
|
||||||
api_key = ninjaGetAccessToken(REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL, api_key)
|
api_key = xyhelperGetAccessToken(REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL, api_key)
|
||||||
if not api_key.startswith("eyJhb"):
|
if not api_key.startswith("eyJhb"):
|
||||||
return jsonify({"error": "refresh_token is wrong or refresh_token url is wrong!"}), 401
|
return jsonify({"error": "refresh_token is wrong or refresh_token url is wrong!"}), 401
|
||||||
add_to_dict(refresh_token, api_key)
|
add_to_dict(refresh_token, api_key)
|
||||||
@@ -2659,7 +2644,7 @@ def updateRefresh_dict():
|
|||||||
if REFRESH_TOACCESS_ENABLEOAI:
|
if REFRESH_TOACCESS_ENABLEOAI:
|
||||||
access_token = oaiGetAccessToken(key)
|
access_token = oaiGetAccessToken(key)
|
||||||
else:
|
else:
|
||||||
access_token = ninjaGetAccessToken(REFRESH_TOACCESS_NINJA_REFRESHTOACCESS_URL, key)
|
access_token = xyhelperGetAccessToken(REFRESH_TOACCESS_XYHELPER_REFRESHTOACCESS_URL, key)
|
||||||
if not access_token.startswith("eyJhb"):
|
if not access_token.startswith("eyJhb"):
|
||||||
logger.debug("refresh_token is wrong or refresh_token url is wrong!")
|
logger.debug("refresh_token is wrong or refresh_token url is wrong!")
|
||||||
error_num += 1
|
error_num += 1
|
||||||
@@ -2667,17 +2652,18 @@ def updateRefresh_dict():
|
|||||||
success_num += 1
|
success_num += 1
|
||||||
logging.info("更新成功: " + str(success_num) + ", 失败: " + str(error_num))
|
logging.info("更新成功: " + str(success_num) + ", 失败: " + str(error_num))
|
||||||
logger.info(f"==========================================")
|
logger.info(f"==========================================")
|
||||||
logging.info("开始更新KEY_FOR_GPTS_INFO_ACCESS_TOKEN和GPTS配置信息......")
|
logging.info("开始更新KEY_FOR_GPTS_INFO_ACCESS_TOKEN和GPTS配置信息.......")
|
||||||
# 加载配置并添加到全局列表
|
# 加载配置并添加到全局列表
|
||||||
gpts_data = load_gpts_config("./data/gpts.json")
|
gpts_data = load_gpts_config("./data/gpts.json")
|
||||||
add_config_to_global_list(BASE_URL, PROXY_API_PREFIX, gpts_data)
|
add_config_to_global_list(BASE_URL, PROXY_API_PREFIX, gpts_data)
|
||||||
|
|
||||||
accessible_model_list = get_accessible_model_list()
|
accessible_model_list = get_accessible_model_list()
|
||||||
|
logger.info(f"当前可用 GPTS 列表: {accessible_model_list}")
|
||||||
|
|
||||||
# 检查列表中是否有重复的模型名称
|
# 检查列表中是否有重复的模型名称
|
||||||
if len(accessible_model_list) != len(set(accessible_model_list)):
|
if len(accessible_model_list) != len(set(accessible_model_list)):
|
||||||
raise Exception("检测到重复的模型名称,请检查环境变量或配置文件。")
|
raise Exception("检测到重复的模型名称,请检查环境变量或配置文件......")
|
||||||
logging.info("更新KEY_FOR_GPTS_INFO_ACCESS_TOKEN和GPTS配置信息成功......")
|
logging.info("更新KEY_FOR_GPTS_INFO_ACCESS_TOKEN和GPTS配置信息成功......")
|
||||||
logger.info(f"当前可用 GPTS 列表: {accessible_model_list}")
|
|
||||||
logger.info(f"==========================================")
|
logger.info(f"==========================================")
|
||||||
|
|
||||||
|
|
||||||
@@ -2686,4 +2672,4 @@ scheduler.add_job(id='updateRefresh_run', func=updateRefresh_dict, trigger='cron
|
|||||||
|
|
||||||
# 运行 Flask 应用
|
# 运行 Flask 应用
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', port=33333, threaded=True)
|
app.run(host='0.0.0.0')
|
||||||
|
|||||||
4
start.sh
4
start.sh
@@ -11,7 +11,7 @@ if [ -z "$PROCESS_WORKERS" ]; then
|
|||||||
export PROCESS_WORKERS
|
export PROCESS_WORKERS
|
||||||
|
|
||||||
if [ -z "$PROCESS_WORKERS" ]; then
|
if [ -z "$PROCESS_WORKERS" ]; then
|
||||||
PROCESS_WORKERS=1
|
PROCESS_WORKERS=2
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -31,4 +31,4 @@ echo "PROCESS_WORKERS: ${PROCESS_WORKERS}"
|
|||||||
echo "PROCESS_THREADS: ${PROCESS_THREADS}"
|
echo "PROCESS_THREADS: ${PROCESS_THREADS}"
|
||||||
|
|
||||||
# 启动 Gunicorn 并使用 tee 命令同时输出日志到文件和控制台
|
# 启动 Gunicorn 并使用 tee 命令同时输出日志到文件和控制台
|
||||||
exec gunicorn -w ${PROCESS_WORKERS} --threads ${PROCESS_THREADS} --bind 0.0.0.0:33333 main:app --access-logfile - --error-logfile - --timeout 60
|
exec gunicorn -w ${PROCESS_WORKERS} --threads ${PROCESS_THREADS} --bind 0.0.0.0:33333 main:app --access-logfile - --error-logfile -
|
||||||
|
|||||||
Reference in New Issue
Block a user