4
4
from typing import AsyncGenerator
5
5
6
6
import httpx
7
- import revChatGPT
8
7
from fastapi .encoders import jsonable_encoder
9
8
from pydantic import parse_obj_as , ValidationError
10
- from revChatGPT .V1 import AsyncChatbot
11
9
12
10
from api .conf import Config , Credentials
13
11
from api .enums import OpenaiWebChatModels , ChatSourceTypes
@@ -128,32 +126,55 @@ async def _check_response(response: httpx.Response) -> None:
128
126
raise error from ex
129
127
130
128
129
+ def make_session () -> httpx .AsyncClient :
130
+ if config .openai_web .proxy is not None :
131
+ proxies = {
132
+ "http://" : config .openai_web .proxy ,
133
+ "https://" : config .openai_web .proxy ,
134
+ }
135
+ session = httpx .AsyncClient (proxies = proxies )
136
+ else :
137
+ session = httpx .AsyncClient ()
138
+ session .headers .clear ()
139
+ session .headers .update (
140
+ {
141
+ "Accept" : "text/event-stream" ,
142
+ "Authorization" : f"Bearer { credentials .openai_web_access_token } " ,
143
+ "Content-Type" : "application/json" ,
144
+ "X-Openai-Assistant-App-Id" : "" ,
145
+ "Connection" : "close" ,
146
+ "Accept-Language" : "en-US,en;q=0.9" ,
147
+ "Referer" : "https://chat.openai.com/chat" ,
148
+ },
149
+ )
150
+ return session
151
+
152
+
131
153
@singleton_with_lock
132
154
class OpenaiWebChatManager :
133
155
"""
134
156
TODO: 解除 revChatGPT 依赖
135
157
"""
136
158
137
159
def __init__ (self ):
138
- self .chatbot = AsyncChatbot ({
139
- "access_token" : credentials .chatgpt_access_token ,
140
- "paid" : config .openai_web .is_plus_account ,
141
- "model" : "text-davinci-002-render-sha" , # default model
142
- }, base_url = config .openai_web .chatgpt_base_url )
160
+ self .session = make_session ()
143
161
self .semaphore = asyncio .Semaphore (1 )
144
162
145
163
def is_busy (self ):
146
164
return self .semaphore .locked ()
147
165
166
+ def reset_session (self ):
167
+ self .session = make_session ()
168
+
148
169
async def get_conversations (self , timeout = None ):
149
170
all_conversations = []
150
171
offset = 0
151
172
limit = 80
152
173
while True :
153
- url = f"{ self . chatbot . base_url } conversations?offset={ offset } &limit={ limit } "
174
+ url = f"{ config . openai_web . chatgpt_base_url } conversations?offset={ offset } &limit={ limit } "
154
175
if timeout is None :
155
176
timeout = httpx .Timeout (config .openai_web .common_timeout )
156
- response = await self .chatbot . session .get (url , timeout = timeout )
177
+ response = await self .session .get (url , timeout = timeout )
157
178
await _check_response (response )
158
179
data = json .loads (response .text )
159
180
conversations = data ["items" ]
@@ -165,9 +186,8 @@ async def get_conversations(self, timeout=None):
165
186
return all_conversations
166
187
167
188
async def get_conversation_history (self , conversation_id : uuid .UUID | str ) -> OpenaiWebConversationHistoryDocument :
168
- # result = await self.chatbot.get_msg_history(conversation_id)
169
- url = f"{ self .chatbot .base_url } conversation/{ conversation_id } "
170
- response = await self .chatbot .session .get (url , timeout = None )
189
+ url = f"{ config .openai_web .chatgpt_base_url } conversation/{ conversation_id } "
190
+ response = await self .session .get (url , timeout = None )
171
191
response .encoding = 'utf-8'
172
192
await _check_response (response )
173
193
result = json .loads (response .text )
@@ -198,7 +218,10 @@ async def get_conversation_history(self, conversation_id: uuid.UUID | str) -> Op
198
218
return doc
199
219
200
220
async def clear_conversations (self ):
201
- await self .chatbot .clear_conversations ()
221
+ # await self.chatbot.clear_conversations()
222
+ url = f"{ config .openai_web .chatgpt_base_url } conversations"
223
+ response = await self .session .patch (url , data = {"is_visible" : False })
224
+ await _check_response (response )
202
225
203
226
async def ask (self , content : str , conversation_id : uuid .UUID = None , parent_id : uuid .UUID = None ,
204
227
model : OpenaiWebChatModels = None , plugin_ids : list [str ] = None , ** _kwargs ):
@@ -238,9 +261,9 @@ async def ask(self, content: str, conversation_id: uuid.UUID = None, parent_id:
238
261
239
262
timeout = httpx .Timeout (Config ().openai_web .common_timeout , read = Config ().openai_web .ask_timeout )
240
263
241
- async with self .chatbot . session .stream (
264
+ async with self .session .stream (
242
265
method = "POST" ,
243
- url = f"{ self . chatbot . base_url } conversation" ,
266
+ url = f"{ config . openai_web . chatgpt_base_url } conversation" ,
244
267
data = json .dumps (data ),
245
268
timeout = timeout ,
246
269
) as response :
@@ -267,18 +290,23 @@ async def ask(self, content: str, conversation_id: uuid.UUID = None, parent_id:
267
290
yield line
268
291
269
292
async def delete_conversation (self , conversation_id : str ):
270
- await self .chatbot .delete_conversation (conversation_id )
293
+ # await self.chatbot.delete_conversation(conversation_id)
294
+ url = f"{ config .openai_web .chatgpt_base_url } conversation/{ conversation_id } "
295
+ response = await self .session .patch (url , data = '{"is_visible": false}' )
296
+ await _check_response (response )
271
297
272
298
async def set_conversation_title (self , conversation_id : str , title : str ):
273
- """Hack change_title to set title in utf-8"""
274
- await self .chatbot .change_title (conversation_id , title )
299
+ url = f"{ config .openai_web .chatgpt_base_url } conversation/{ conversation_id } "
300
+ response = await self .session .patch (url , data = f'{{"title": "{ title } "}}' )
301
+ await _check_response (response )
275
302
276
303
async def generate_conversation_title (self , conversation_id : str , message_id : str ):
277
- """Hack gen_title to get title"""
278
- await self .chatbot .gen_title (conversation_id , message_id )
279
-
280
- def reset_chat (self ):
281
- self .chatbot .reset_chat ()
304
+ url = f"{ config .openai_web .chatgpt_base_url } conversation/gen_title/{ conversation_id } "
305
+ response = await self .session .post (
306
+ url ,
307
+ data = json .dumps ({"message_id" : message_id , "model" : "text-davinci-002-render" }),
308
+ )
309
+ await _check_response (response )
282
310
283
311
async def get_plugin_manifests (self , statuses = "approved" , is_installed = None , offset = 0 , limit = 250 ):
284
312
if not config .openai_web .is_plus_account :
@@ -290,8 +318,8 @@ async def get_plugin_manifests(self, statuses="approved", is_installed=None, off
290
318
}
291
319
if is_installed is not None :
292
320
params ["is_installed" ] = is_installed
293
- response = await self .chatbot . session .get (
294
- url = f"{ self . chatbot . base_url } aip/p" ,
321
+ response = await self .session .get (
322
+ url = f"{ config . openai_web . chatgpt_base_url } aip/p" ,
295
323
params = params ,
296
324
timeout = config .openai_web .ask_timeout
297
325
)
@@ -301,8 +329,8 @@ async def get_plugin_manifests(self, statuses="approved", is_installed=None, off
301
329
async def change_plugin_user_settings (self , plugin_id : str , setting : OpenaiChatPluginUserSettings ):
302
330
if not config .openai_web .is_plus_account :
303
331
raise InvalidParamsException ("errors.notPlusChatgptAccount" )
304
- response = await self .chatbot . session .patch (
305
- url = f"{ self . chatbot . base_url } aip/p/{ plugin_id } /user-settings" ,
332
+ response = await self .session .patch (
333
+ url = f"{ config . openai_web . chatgpt_base_url } aip/p/{ plugin_id } /user-settings" ,
306
334
json = setting .dict (exclude_unset = True , exclude_none = True ),
307
335
)
308
336
await _check_response (response )
0 commit comments