mirror of
https://github.com/Yanyutin753/RefreshToV1Api.git
synced 2025-10-13 22:56:31 +00:00
[feat] 重磅更新:支持大部分GPTS模型
This commit is contained in:
43
Readme.md
43
Readme.md
@@ -8,6 +8,12 @@
|
||||
|
||||
# 更新日志
|
||||
|
||||
### 0.1.0
|
||||
|
||||
- 重磅更新
|
||||
|
||||
- 已支持访问大部分的GPTS
|
||||
|
||||
### 0.0.11
|
||||
|
||||
- 修复一些偶现的bug
|
||||
@@ -43,11 +49,11 @@
|
||||
|
||||
目前支持的模型包括:
|
||||
|
||||
1. gpt-4-classic:纯文字生成的 GPT-4,未加入任何插件,对应的是官方的 GPT-4-Classic
|
||||
1. gpt-4-s:支持代码解释器、bing联网、dalle绘图的 GPT-4,对应的是官方的默认 GPT-4(绘图的响应有时候有些不稳定)
|
||||
|
||||
2. gpt-4-s:支持代码解释器、bing联网、dalle绘图的 GPT-4,对应的是官方的默认 GPT-4(绘图的响应有时候有些不稳定)
|
||||
2. gpt-4-mobile:支持代码解释器、bing联网、dalle绘图的 GPT-4,对应的是官方的手机版 GPT-4,截止至2023年12月15日,本模型使用量不计入 GPT-4 用量(即不受每 3 小时 40 次的限制)
|
||||
|
||||
3. gpt-4-mobile:支持代码解释器、bing联网、dalle绘图的 GPT-4,对应的是官方的手机版 GPT-4,截止至2023年12月15日,本模型使用量不计入 GPT-4 用量(即不受每 3 小时 40 次的限制)
|
||||
3. 几乎所有的 GPTS(配置方式见下文)
|
||||
|
||||
# Docker-Compose 部署
|
||||
|
||||
@@ -55,7 +61,30 @@
|
||||
|
||||
# 环境变量说明:
|
||||
|
||||
- UPLOAD_BASE_URL 用于dalle模型生成图片的时候展示所用,需要设置为使用如 [ChatGPT-Next-Web](https://github.com/ChatGPTNextWebTeam/ChatGPT-Next-Web) 的用户可以访问到的 Uploader 容器地址,如:http://127.0.0.1:50012
|
||||
- UPLOAD_BASE_URL:用于dalle模型生成图片的时候展示所用,需要设置为使用如 [ChatGPT-Next-Web](https://github.com/ChatGPTNextWebTeam/ChatGPT-Next-Web) 的用户可以访问到的 Uploader 容器地址,如:http://127.0.0.1:50012
|
||||
|
||||
- KEY_FOR_GPTS_INFO:仅获取 GPTS 信息的 key,需要该 key 能够访问所有配置的 GPTS。后续发送消息仍需要在请求头携带请求所用的 key。
|
||||
|
||||
# GPTS配置说明
|
||||
|
||||
如果需要使用 GPTS,需要修改 `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`,而模型名可以自定义。
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"gpt-4-classic": {
|
||||
"id":"g-YyyyMT9XH-chatgpt-classic"
|
||||
},
|
||||
"pandoraNext":{
|
||||
"id":"g-CFsXuTRfy-pandoranextzhu-shou"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
注意:使用该配置的时候需要保证正确填写 `docker-compose.yml` 的环境变量 `KEY_FOR_GPTS_INFO`,同时该变量设置的 `key` 允许访问所有配置的 GPTS。
|
||||
|
||||
# 示例
|
||||
|
||||
@@ -71,7 +100,7 @@ services:
|
||||
environment:
|
||||
- OPENAI_API_KEY=<Pandora-Next 的 fk>
|
||||
- BASE_URL=<backend-to-api容器地址>
|
||||
- CUSTOM_MODELS=+gpt-4-s,+gpt-4-classic,+gpt-4-mobile
|
||||
- CUSTOM_MODELS=+gpt-4-s,+gpt-4-mobile,+<gpts.json 中的模型名>
|
||||
|
||||
```
|
||||
|
||||
@@ -92,3 +121,7 @@ services:
|
||||
### GPT-4-Mobile
|
||||
|
||||

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

|
||||
|
@@ -10,10 +10,11 @@ services:
|
||||
- BASE_URL=<Pandora-Next的部署地址,如:https://pandoranext.com>
|
||||
- PROXY_API_PREFIX=<Pandora-Next的PROXY_API_PREFIX>
|
||||
- UPLOAD_BASE_URL=<Uploader 容器可以访问到的地址,如:http://127.0.0.1:50012>
|
||||
- KEY_FOR_GPTS_INFO=<一个仅用于获取GPTs信息的fk> # 如果不需要额外使用gpts,可以不填
|
||||
volumes:
|
||||
- ./log:/app/log
|
||||
- ./images:/app/images
|
||||
|
||||
- ./gpts.json:/app/gpts.json
|
||||
|
||||
uploader:
|
||||
image: wizerd/pandora-to-api:latest
|
||||
|
5
gpts.json
Normal file
5
gpts.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"gpt-4-classic": {
|
||||
"id":"g-YyyyMT9XH-chatgpt-classic"
|
||||
}
|
||||
}
|
210
main.py
210
main.py
@@ -17,6 +17,85 @@ def generate_unique_id(prefix):
|
||||
return unique_id
|
||||
|
||||
|
||||
def get_accessible_model_list():
|
||||
return [config['name'] for config in gpts_configurations]
|
||||
|
||||
|
||||
def find_model_config(model_name):
|
||||
for config in gpts_configurations:
|
||||
if config['name'] == model_name:
|
||||
return config
|
||||
return None
|
||||
|
||||
# 从 gpts.json 读取配置
|
||||
def load_gpts_config(file_path):
|
||||
with open(file_path, 'r', encoding='utf-8') as file:
|
||||
return json.load(file)
|
||||
|
||||
# 根据 ID 发送请求并获取配置信息
|
||||
def fetch_gizmo_info(base_url, proxy_api_prefix, model_id):
|
||||
url = f"{base_url}/{proxy_api_prefix}/backend-api/gizmos/{model_id}"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {KEY_FOR_GPTS_INFO}"
|
||||
}
|
||||
|
||||
response = requests.get(url, headers=headers)
|
||||
# print(f"fetch_gizmo_info_response: {response.text}")
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
return None
|
||||
|
||||
gpts_configurations = [
|
||||
{
|
||||
"name":"gpt-4-s"
|
||||
},
|
||||
{
|
||||
"name":"gpt-4-mobile"
|
||||
}
|
||||
]
|
||||
|
||||
# 将配置添加到全局列表
|
||||
def add_config_to_global_list(base_url, proxy_api_prefix, gpts_data):
|
||||
global gpts_configurations
|
||||
# print(f"gpts_data: {gpts_data}")
|
||||
for model_name, model_info in gpts_data.items():
|
||||
# print(f"model_name: {model_name}")
|
||||
# print(f"model_info: {model_info}")
|
||||
model_id = model_info['id']
|
||||
gizmo_info = fetch_gizmo_info(base_url, proxy_api_prefix, model_id)
|
||||
if gizmo_info:
|
||||
gpts_configurations.append({
|
||||
'name': model_name,
|
||||
'id': model_id,
|
||||
'config': gizmo_info
|
||||
})
|
||||
|
||||
def generate_gpts_payload(model):
|
||||
model_config = find_model_config(model)
|
||||
if model_config:
|
||||
gizmo_info = model_config['config']
|
||||
gizmo_id = gizmo_info['gizmo']['id']
|
||||
|
||||
payload = {
|
||||
"action": "next",
|
||||
"messages": [],
|
||||
"parent_message_id": str(uuid.uuid4()),
|
||||
"model": "gpt-4-gizmo",
|
||||
"timezone_offset_min": -480,
|
||||
"history_and_training_disabled": False,
|
||||
"conversation_mode": {
|
||||
"gizmo": gizmo_info,
|
||||
"kind": "gizmo_interaction",
|
||||
"gizmo_id": gizmo_id
|
||||
},
|
||||
"force_paragen": False,
|
||||
"force_rate_limit": False
|
||||
}
|
||||
return payload
|
||||
else:
|
||||
return None
|
||||
|
||||
# 创建 Flask 应用
|
||||
app = Flask(__name__)
|
||||
|
||||
@@ -25,9 +104,10 @@ app = Flask(__name__)
|
||||
BASE_URL = os.getenv('BASE_URL', '')
|
||||
PROXY_API_PREFIX = os.getenv('PROXY_API_PREFIX', '')
|
||||
UPLOAD_BASE_URL = os.getenv('UPLOAD_BASE_URL', '')
|
||||
KEY_FOR_GPTS_INFO = os.getenv('KEY_FOR_GPTS_INFO', '')
|
||||
|
||||
VERSION = '0.0.11'
|
||||
UPDATE_INFO = '修复一些偶现的bug'
|
||||
VERSION = '0.1.0'
|
||||
UPDATE_INFO = '适配大部分GPTS模型'
|
||||
|
||||
with app.app_context():
|
||||
# 输出版本信息
|
||||
@@ -47,6 +127,21 @@ with app.app_context():
|
||||
|
||||
print(f"==========================================")
|
||||
|
||||
print(f"GPTS 配置信息")
|
||||
|
||||
# 加载配置并添加到全局列表
|
||||
gpts_data = load_gpts_config("./gpts.json")
|
||||
add_config_to_global_list(BASE_URL, PROXY_API_PREFIX, gpts_data)
|
||||
# print("当前可用GPTS:" + get_accessible_model_list())
|
||||
# 输出当前可用 GPTS name
|
||||
print(f"当前可用 GPTS 列表: {get_accessible_model_list()}")
|
||||
|
||||
print(f"==========================================")
|
||||
|
||||
# print(f"GPTs Payload 生成测试")
|
||||
|
||||
# print(f"gpt-4-classic: {generate_gpts_payload('gpt-4-classic')}")
|
||||
|
||||
|
||||
# 定义获取 token 的函数
|
||||
def get_token():
|
||||
@@ -59,7 +154,8 @@ def get_token():
|
||||
return None
|
||||
|
||||
import os
|
||||
accessable_model_list = ['gpt-4-classic', 'gpt-4-s', 'gpt-4-mobile']
|
||||
|
||||
|
||||
|
||||
# 定义发送请求的函数
|
||||
def send_text_prompt_and_get_response(messages, api_key, stream, model):
|
||||
@@ -82,103 +178,7 @@ def send_text_prompt_and_get_response(messages, api_key, stream, model):
|
||||
payload = {}
|
||||
|
||||
print(f"model: {model}")
|
||||
|
||||
if model == 'gpt-4-classic':
|
||||
payload = {
|
||||
# 构建 payload
|
||||
"action": "next",
|
||||
"messages": formatted_messages,
|
||||
"parent_message_id": str(uuid.uuid4()),
|
||||
"model": "gpt-4-gizmo",
|
||||
"timezone_offset_min": -480,
|
||||
"history_and_training_disabled": False,
|
||||
"conversation_mode": {
|
||||
"gizmo": {
|
||||
"gizmo": {
|
||||
"id": "g-YyyyMT9XH",
|
||||
"organization_id": "org-OROoM5KiDq6bcfid37dQx4z4",
|
||||
"short_url": "g-YyyyMT9XH-chatgpt-classic",
|
||||
"author": {
|
||||
"user_id": "user-u7SVk5APwT622QC7DPe41GHJ",
|
||||
"display_name": "ChatGPT",
|
||||
"link_to":None,
|
||||
"selected_display": "name",
|
||||
"is_verified":True
|
||||
},
|
||||
"voice": {
|
||||
"id": "ember"
|
||||
},
|
||||
"workspace_id":None,
|
||||
"model":None,
|
||||
"instructions":None,
|
||||
"settings":None,
|
||||
"display": {
|
||||
"name": "ChatGPT Classic",
|
||||
"description": "The latest version of GPT-4 with no additional capabilities",
|
||||
"welcome_message": "Hello",
|
||||
"prompt_starters":None,
|
||||
"profile_picture_url": "",
|
||||
"categories": []
|
||||
},
|
||||
"share_recipient": "marketplace",
|
||||
"updated_at": "2023-11-26T17:46:07.341305+00:00",
|
||||
"last_interacted_at": "2023-12-11T09:49:34.943245+00:00",
|
||||
"tags": [
|
||||
"public",
|
||||
"first_party"
|
||||
],
|
||||
"version":None,
|
||||
"live_version":None,
|
||||
"training_disabled":None,
|
||||
"allowed_sharing_recipients":None,
|
||||
"review_info":None,
|
||||
"appeal_info":None,
|
||||
"vanity_metrics":None
|
||||
},
|
||||
"tools": [],
|
||||
"files": [],
|
||||
"product_features": {
|
||||
"attachments": {
|
||||
"type": "retrieval",
|
||||
"accepted_mime_types": [
|
||||
"text/x-script.python",
|
||||
"application/x-latext",
|
||||
"text/x-c++",
|
||||
"text/javascript",
|
||||
"text/x-java",
|
||||
"text/x-typescript",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"text/x-csharp",
|
||||
"text/plain",
|
||||
"application/pdf",
|
||||
"text/x-sh",
|
||||
"text/markdown",
|
||||
"text/x-c",
|
||||
"text/x-ruby",
|
||||
"text/x-tex",
|
||||
"text/x-php",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"application/json",
|
||||
"text/html",
|
||||
"application/msword"
|
||||
],
|
||||
"image_mime_types": [
|
||||
"image/webp",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/gif"
|
||||
],
|
||||
"can_accept_all_mime_types":True
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": "gizmo_interaction",
|
||||
"gizmo_id": "g-YyyyMT9XH"
|
||||
},
|
||||
"force_paragen":False,
|
||||
"force_rate_limit":False
|
||||
}
|
||||
elif model == 'gpt-4-s':
|
||||
if model == 'gpt-4-s':
|
||||
payload = {
|
||||
# 构建 payload
|
||||
"action": "next",
|
||||
@@ -202,6 +202,10 @@ def send_text_prompt_and_get_response(messages, api_key, stream, model):
|
||||
"history_and_training_disabled": False,
|
||||
"conversation_mode":{"kind":"primary_assistant"},"force_paragen":False,"force_rate_limit":False
|
||||
}
|
||||
else:
|
||||
payload = generate_gpts_payload(model)
|
||||
if not payload:
|
||||
raise Exception('model is not accessible')
|
||||
response = requests.post(url, headers=headers, json=payload, stream=True)
|
||||
# print(response)
|
||||
return response
|
||||
@@ -325,8 +329,10 @@ def chat_completions():
|
||||
data = request.json
|
||||
messages = data.get('messages')
|
||||
model = data.get('model')
|
||||
if model not in accessable_model_list:
|
||||
return jsonify({"error": "model is not accessable"}), 401
|
||||
accessible_model_list = get_accessible_model_list()
|
||||
if model not in accessible_model_list:
|
||||
return jsonify({"error": "model is not accessible"}), 401
|
||||
|
||||
stream = data.get('stream', False)
|
||||
|
||||
auth_header = request.headers.get('Authorization')
|
||||
|
Reference in New Issue
Block a user