Your Name commited on
Commit
ee94fa6
1 Parent(s): d2e46f6

拆分成两个文件

Browse files
request_llm/bridge_newbing.py CHANGED
@@ -4,408 +4,7 @@
4
  https://github.com/acheong08/EdgeGPT
5
  ========================================================================
6
  """
7
-
8
-
9
- import argparse
10
- import asyncio
11
- import json
12
- import os
13
- import random
14
- import re
15
- import ssl
16
- import sys
17
- import uuid
18
- from enum import Enum
19
- from typing import Generator
20
- from typing import Literal
21
- from typing import Optional
22
- from typing import Union
23
- import certifi
24
- import httpx
25
- import websockets.client as websockets
26
-
27
- DELIMITER = "\x1e"
28
-
29
-
30
- # Generate random IP between range 13.104.0.0/14
31
- FORWARDED_IP = (
32
- f"13.{random.randint(104, 107)}.{random.randint(0, 255)}.{random.randint(0, 255)}"
33
- )
34
-
35
- HEADERS = {
36
- "accept": "application/json",
37
- "accept-language": "en-US,en;q=0.9",
38
- "content-type": "application/json",
39
- "sec-ch-ua": '"Not_A Brand";v="99", "Microsoft Edge";v="110", "Chromium";v="110"',
40
- "sec-ch-ua-arch": '"x86"',
41
- "sec-ch-ua-bitness": '"64"',
42
- "sec-ch-ua-full-version": '"109.0.1518.78"',
43
- "sec-ch-ua-full-version-list": '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"',
44
- "sec-ch-ua-mobile": "?0",
45
- "sec-ch-ua-model": "",
46
- "sec-ch-ua-platform": '"Windows"',
47
- "sec-ch-ua-platform-version": '"15.0.0"',
48
- "sec-fetch-dest": "empty",
49
- "sec-fetch-mode": "cors",
50
- "sec-fetch-site": "same-origin",
51
- "x-ms-client-request-id": str(uuid.uuid4()),
52
- "x-ms-useragent": "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Win32",
53
- "Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx",
54
- "Referrer-Policy": "origin-when-cross-origin",
55
- "x-forwarded-for": FORWARDED_IP,
56
- }
57
-
58
- HEADERS_INIT_CONVER = {
59
- "authority": "edgeservices.bing.com",
60
- "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
61
- "accept-language": "en-US,en;q=0.9",
62
- "cache-control": "max-age=0",
63
- "sec-ch-ua": '"Chromium";v="110", "Not A(Brand";v="24", "Microsoft Edge";v="110"',
64
- "sec-ch-ua-arch": '"x86"',
65
- "sec-ch-ua-bitness": '"64"',
66
- "sec-ch-ua-full-version": '"110.0.1587.69"',
67
- "sec-ch-ua-full-version-list": '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"',
68
- "sec-ch-ua-mobile": "?0",
69
- "sec-ch-ua-model": '""',
70
- "sec-ch-ua-platform": '"Windows"',
71
- "sec-ch-ua-platform-version": '"15.0.0"',
72
- "sec-fetch-dest": "document",
73
- "sec-fetch-mode": "navigate",
74
- "sec-fetch-site": "none",
75
- "sec-fetch-user": "?1",
76
- "upgrade-insecure-requests": "1",
77
- "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69",
78
- "x-edge-shopping-flag": "1",
79
- "x-forwarded-for": FORWARDED_IP,
80
- }
81
-
82
- ssl_context = ssl.create_default_context()
83
- ssl_context.load_verify_locations(certifi.where())
84
-
85
-
86
- class NotAllowedToAccess(Exception):
87
- pass
88
-
89
-
90
- class ConversationStyle(Enum):
91
- creative = "h3imaginative,clgalileo,gencontentv3"
92
- balanced = "galileo"
93
- precise = "h3precise,clgalileo"
94
-
95
-
96
- CONVERSATION_STYLE_TYPE = Optional[
97
- Union[ConversationStyle, Literal["creative", "balanced", "precise"]]
98
- ]
99
-
100
-
101
- def _append_identifier(msg: dict) -> str:
102
- """
103
- Appends special character to end of message to identify end of message
104
- """
105
- # Convert dict to json string
106
- return json.dumps(msg) + DELIMITER
107
-
108
-
109
- def _get_ran_hex(length: int = 32) -> str:
110
- """
111
- Returns random hex string
112
- """
113
- return "".join(random.choice("0123456789abcdef") for _ in range(length))
114
-
115
-
116
- class _ChatHubRequest:
117
- """
118
- Request object for ChatHub
119
- """
120
-
121
- def __init__(
122
- self,
123
- conversation_signature: str,
124
- client_id: str,
125
- conversation_id: str,
126
- invocation_id: int = 0,
127
- ) -> None:
128
- self.struct: dict = {}
129
-
130
- self.client_id: str = client_id
131
- self.conversation_id: str = conversation_id
132
- self.conversation_signature: str = conversation_signature
133
- self.invocation_id: int = invocation_id
134
-
135
- def update(
136
- self,
137
- prompt,
138
- conversation_style,
139
- options,
140
- ) -> None:
141
- """
142
- Updates request object
143
- """
144
- if options is None:
145
- options = [
146
- "deepleo",
147
- "enable_debug_commands",
148
- "disable_emoji_spoken_text",
149
- "enablemm",
150
- ]
151
- if conversation_style:
152
- if not isinstance(conversation_style, ConversationStyle):
153
- conversation_style = getattr(ConversationStyle, conversation_style)
154
- options = [
155
- "nlu_direct_response_filter",
156
- "deepleo",
157
- "disable_emoji_spoken_text",
158
- "responsible_ai_policy_235",
159
- "enablemm",
160
- conversation_style.value,
161
- "dtappid",
162
- "cricinfo",
163
- "cricinfov2",
164
- "dv3sugg",
165
- ]
166
- self.struct = {
167
- "arguments": [
168
- {
169
- "source": "cib",
170
- "optionsSets": options,
171
- "sliceIds": [
172
- "222dtappid",
173
- "225cricinfo",
174
- "224locals0",
175
- ],
176
- "traceId": _get_ran_hex(32),
177
- "isStartOfSession": self.invocation_id == 0,
178
- "message": {
179
- "author": "user",
180
- "inputMethod": "Keyboard",
181
- "text": prompt,
182
- "messageType": "Chat",
183
- },
184
- "conversationSignature": self.conversation_signature,
185
- "participant": {
186
- "id": self.client_id,
187
- },
188
- "conversationId": self.conversation_id,
189
- },
190
- ],
191
- "invocationId": str(self.invocation_id),
192
- "target": "chat",
193
- "type": 4,
194
- }
195
- self.invocation_id += 1
196
-
197
-
198
- class _Conversation:
199
- """
200
- Conversation API
201
- """
202
-
203
- def __init__(
204
- self,
205
- cookies,
206
- proxy,
207
- ) -> None:
208
- self.struct: dict = {
209
- "conversationId": None,
210
- "clientId": None,
211
- "conversationSignature": None,
212
- "result": {"value": "Success", "message": None},
213
- }
214
- self.proxy = proxy
215
- proxy = (
216
- proxy
217
- or os.environ.get("all_proxy")
218
- or os.environ.get("ALL_PROXY")
219
- or os.environ.get("https_proxy")
220
- or os.environ.get("HTTPS_PROXY")
221
- or None
222
- )
223
- if proxy is not None and proxy.startswith("socks5h://"):
224
- proxy = "socks5://" + proxy[len("socks5h://") :]
225
- self.session = httpx.Client(
226
- proxies=proxy,
227
- timeout=30,
228
- headers=HEADERS_INIT_CONVER,
229
- )
230
- for cookie in cookies:
231
- self.session.cookies.set(cookie["name"], cookie["value"])
232
-
233
- # Send GET request
234
- response = self.session.get(
235
- url=os.environ.get("BING_PROXY_URL")
236
- or "https://edgeservices.bing.com/edgesvc/turing/conversation/create",
237
- )
238
- if response.status_code != 200:
239
- response = self.session.get(
240
- "https://edge.churchless.tech/edgesvc/turing/conversation/create",
241
- )
242
- if response.status_code != 200:
243
- print(f"Status code: {response.status_code}")
244
- print(response.text)
245
- print(response.url)
246
- raise Exception("Authentication failed")
247
- try:
248
- self.struct = response.json()
249
- except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc:
250
- raise Exception(
251
- "Authentication failed. You have not been accepted into the beta.",
252
- ) from exc
253
- if self.struct["result"]["value"] == "UnauthorizedRequest":
254
- raise NotAllowedToAccess(self.struct["result"]["message"])
255
-
256
-
257
- class _ChatHub:
258
- """
259
- Chat API
260
- """
261
-
262
- def __init__(self, conversation) -> None:
263
- self.wss = None
264
- self.request: _ChatHubRequest
265
- self.loop: bool
266
- self.task: asyncio.Task
267
- print(conversation.struct)
268
- self.request = _ChatHubRequest(
269
- conversation_signature=conversation.struct["conversationSignature"],
270
- client_id=conversation.struct["clientId"],
271
- conversation_id=conversation.struct["conversationId"],
272
- )
273
-
274
- async def ask_stream(
275
- self,
276
- prompt: str,
277
- wss_link: str,
278
- conversation_style: CONVERSATION_STYLE_TYPE = None,
279
- raw: bool = False,
280
- options: dict = None,
281
- ) -> Generator[str, None, None]:
282
- """
283
- Ask a question to the bot
284
- """
285
- if self.wss and not self.wss.closed:
286
- await self.wss.close()
287
- # Check if websocket is closed
288
- self.wss = await websockets.connect(
289
- wss_link,
290
- extra_headers=HEADERS,
291
- max_size=None,
292
- ssl=ssl_context,
293
- )
294
- await self._initial_handshake()
295
- # Construct a ChatHub request
296
- self.request.update(
297
- prompt=prompt,
298
- conversation_style=conversation_style,
299
- options=options,
300
- )
301
- # Send request
302
- await self.wss.send(_append_identifier(self.request.struct))
303
- final = False
304
- while not final:
305
- objects = str(await self.wss.recv()).split(DELIMITER)
306
- for obj in objects:
307
- if obj is None or not obj:
308
- continue
309
- response = json.loads(obj)
310
- if response.get("type") != 2 and raw:
311
- yield False, response
312
- elif response.get("type") == 1 and response["arguments"][0].get(
313
- "messages",
314
- ):
315
- resp_txt = response["arguments"][0]["messages"][0]["adaptiveCards"][
316
- 0
317
- ]["body"][0].get("text")
318
- yield False, resp_txt
319
- elif response.get("type") == 2:
320
- final = True
321
- yield True, response
322
-
323
- async def _initial_handshake(self) -> None:
324
- await self.wss.send(_append_identifier({"protocol": "json", "version": 1}))
325
- await self.wss.recv()
326
-
327
- async def close(self) -> None:
328
- """
329
- Close the connection
330
- """
331
- if self.wss and not self.wss.closed:
332
- await self.wss.close()
333
-
334
-
335
- class Chatbot:
336
- """
337
- Combines everything to make it seamless
338
- """
339
-
340
- def __init__(
341
- self,
342
- cookies,
343
- proxy
344
- ) -> None:
345
- if cookies is None:
346
- cookies = {}
347
- self.cookies = cookies
348
- self.proxy = proxy
349
- self.chat_hub: _ChatHub = _ChatHub(
350
- _Conversation(self.cookies, self.proxy),
351
- )
352
-
353
- async def ask(
354
- self,
355
- prompt: str,
356
- wss_link: str,
357
- conversation_style: CONVERSATION_STYLE_TYPE = None,
358
- options: dict = None,
359
- ) -> dict:
360
- """
361
- Ask a question to the bot
362
- """
363
- async for final, response in self.chat_hub.ask_stream(
364
- prompt=prompt,
365
- conversation_style=conversation_style,
366
- wss_link=wss_link,
367
- options=options,
368
- ):
369
- if final:
370
- return response
371
- await self.chat_hub.wss.close()
372
- return None
373
-
374
- async def ask_stream(
375
- self,
376
- prompt: str,
377
- wss_link: str,
378
- conversation_style: CONVERSATION_STYLE_TYPE = None,
379
- raw: bool = False,
380
- options: dict = None,
381
- ) -> Generator[str, None, None]:
382
- """
383
- Ask a question to the bot
384
- """
385
- async for response in self.chat_hub.ask_stream(
386
- prompt=prompt,
387
- conversation_style=conversation_style,
388
- wss_link=wss_link,
389
- raw=raw,
390
- options=options,
391
- ):
392
- yield response
393
-
394
- async def close(self) -> None:
395
- """
396
- Close the connection
397
- """
398
- await self.chat_hub.close()
399
-
400
- async def reset(self) -> None:
401
- """
402
- Reset the conversation
403
- """
404
- await self.close()
405
- self.chat_hub = _ChatHub(_Conversation(self.cookies, self.proxy))
406
-
407
-
408
-
409
  load_message = "等待NewBing响应。"
410
 
411
  """
@@ -414,12 +13,15 @@ load_message = "等待NewBing响应。"
414
  ========================================================================
415
  """
416
  import time
 
 
 
417
  import importlib
418
  import threading
419
  from toolbox import update_ui, get_conf, trimmed_format_exc
420
  from multiprocessing import Process, Pipe
421
 
422
- class GetNewBingHandle(Process):
423
  def __init__(self):
424
  super().__init__(daemon=True)
425
  self.parent, self.child = Pipe()
@@ -522,7 +124,7 @@ class GetNewBingHandle(Process):
522
  raise RuntimeError(f"不能加载Newbing组件。NEWBING_COOKIES未填写或有格式错误。")
523
 
524
  try:
525
- self.newbing_model = Chatbot(proxy=self.proxies_https, cookies=cookies)
526
  except:
527
  self.success = False
528
  tb_str = '\n```\n' + trimmed_format_exc() + '\n```\n'
@@ -588,7 +190,7 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="",
588
  """
589
  global newbing_handle
590
  if (newbing_handle is None) or (not newbing_handle.success):
591
- newbing_handle = GetNewBingHandle()
592
  observe_window[0] = load_message + "\n\n" + newbing_handle.info
593
  if not newbing_handle.success:
594
  error = newbing_handle.info
@@ -619,7 +221,7 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
619
 
620
  global newbing_handle
621
  if (newbing_handle is None) or (not newbing_handle.success):
622
- newbing_handle = GetNewBingHandle()
623
  chatbot[-1] = (inputs, load_message + "\n\n" + newbing_handle.info)
624
  yield from update_ui(chatbot=chatbot, history=[])
625
  if not newbing_handle.success:
 
4
  https://github.com/acheong08/EdgeGPT
5
  ========================================================================
6
  """
7
+ from .edge_gpt import NewbingChatbot
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  load_message = "等待NewBing响应。"
9
 
10
  """
 
13
  ========================================================================
14
  """
15
  import time
16
+ import json
17
+ import re
18
+ import asyncio
19
  import importlib
20
  import threading
21
  from toolbox import update_ui, get_conf, trimmed_format_exc
22
  from multiprocessing import Process, Pipe
23
 
24
+ class NewBingHandle(Process):
25
  def __init__(self):
26
  super().__init__(daemon=True)
27
  self.parent, self.child = Pipe()
 
124
  raise RuntimeError(f"不能加载Newbing组件。NEWBING_COOKIES未填写或有格式错误。")
125
 
126
  try:
127
+ self.newbing_model = NewbingChatbot(proxy=self.proxies_https, cookies=cookies)
128
  except:
129
  self.success = False
130
  tb_str = '\n```\n' + trimmed_format_exc() + '\n```\n'
 
190
  """
191
  global newbing_handle
192
  if (newbing_handle is None) or (not newbing_handle.success):
193
+ newbing_handle = NewBingHandle()
194
  observe_window[0] = load_message + "\n\n" + newbing_handle.info
195
  if not newbing_handle.success:
196
  error = newbing_handle.info
 
221
 
222
  global newbing_handle
223
  if (newbing_handle is None) or (not newbing_handle.success):
224
+ newbing_handle = NewBingHandle()
225
  chatbot[-1] = (inputs, load_message + "\n\n" + newbing_handle.info)
226
  yield from update_ui(chatbot=chatbot, history=[])
227
  if not newbing_handle.success:
request_llm/edge_gpt.py ADDED
@@ -0,0 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ========================================================================
3
+ 第一部分:来自EdgeGPT.py
4
+ https://github.com/acheong08/EdgeGPT
5
+ ========================================================================
6
+ """
7
+
8
+ import argparse
9
+ import asyncio
10
+ import json
11
+ import os
12
+ import random
13
+ import re
14
+ import ssl
15
+ import sys
16
+ import uuid
17
+ from enum import Enum
18
+ from typing import Generator
19
+ from typing import Literal
20
+ from typing import Optional
21
+ from typing import Union
22
+ import certifi
23
+ import httpx
24
+ import websockets.client as websockets
25
+
26
+ DELIMITER = "\x1e"
27
+
28
+
29
+ # Generate random IP between range 13.104.0.0/14
30
+ FORWARDED_IP = (
31
+ f"13.{random.randint(104, 107)}.{random.randint(0, 255)}.{random.randint(0, 255)}"
32
+ )
33
+
34
+ HEADERS = {
35
+ "accept": "application/json",
36
+ "accept-language": "en-US,en;q=0.9",
37
+ "content-type": "application/json",
38
+ "sec-ch-ua": '"Not_A Brand";v="99", "Microsoft Edge";v="110", "Chromium";v="110"',
39
+ "sec-ch-ua-arch": '"x86"',
40
+ "sec-ch-ua-bitness": '"64"',
41
+ "sec-ch-ua-full-version": '"109.0.1518.78"',
42
+ "sec-ch-ua-full-version-list": '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"',
43
+ "sec-ch-ua-mobile": "?0",
44
+ "sec-ch-ua-model": "",
45
+ "sec-ch-ua-platform": '"Windows"',
46
+ "sec-ch-ua-platform-version": '"15.0.0"',
47
+ "sec-fetch-dest": "empty",
48
+ "sec-fetch-mode": "cors",
49
+ "sec-fetch-site": "same-origin",
50
+ "x-ms-client-request-id": str(uuid.uuid4()),
51
+ "x-ms-useragent": "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Win32",
52
+ "Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx",
53
+ "Referrer-Policy": "origin-when-cross-origin",
54
+ "x-forwarded-for": FORWARDED_IP,
55
+ }
56
+
57
+ HEADERS_INIT_CONVER = {
58
+ "authority": "edgeservices.bing.com",
59
+ "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
60
+ "accept-language": "en-US,en;q=0.9",
61
+ "cache-control": "max-age=0",
62
+ "sec-ch-ua": '"Chromium";v="110", "Not A(Brand";v="24", "Microsoft Edge";v="110"',
63
+ "sec-ch-ua-arch": '"x86"',
64
+ "sec-ch-ua-bitness": '"64"',
65
+ "sec-ch-ua-full-version": '"110.0.1587.69"',
66
+ "sec-ch-ua-full-version-list": '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"',
67
+ "sec-ch-ua-mobile": "?0",
68
+ "sec-ch-ua-model": '""',
69
+ "sec-ch-ua-platform": '"Windows"',
70
+ "sec-ch-ua-platform-version": '"15.0.0"',
71
+ "sec-fetch-dest": "document",
72
+ "sec-fetch-mode": "navigate",
73
+ "sec-fetch-site": "none",
74
+ "sec-fetch-user": "?1",
75
+ "upgrade-insecure-requests": "1",
76
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69",
77
+ "x-edge-shopping-flag": "1",
78
+ "x-forwarded-for": FORWARDED_IP,
79
+ }
80
+
81
+ ssl_context = ssl.create_default_context()
82
+ ssl_context.load_verify_locations(certifi.where())
83
+
84
+
85
+ class NotAllowedToAccess(Exception):
86
+ pass
87
+
88
+
89
+ class ConversationStyle(Enum):
90
+ creative = "h3imaginative,clgalileo,gencontentv3"
91
+ balanced = "galileo"
92
+ precise = "h3precise,clgalileo"
93
+
94
+
95
+ CONVERSATION_STYLE_TYPE = Optional[
96
+ Union[ConversationStyle, Literal["creative", "balanced", "precise"]]
97
+ ]
98
+
99
+
100
+ def _append_identifier(msg: dict) -> str:
101
+ """
102
+ Appends special character to end of message to identify end of message
103
+ """
104
+ # Convert dict to json string
105
+ return json.dumps(msg) + DELIMITER
106
+
107
+
108
+ def _get_ran_hex(length: int = 32) -> str:
109
+ """
110
+ Returns random hex string
111
+ """
112
+ return "".join(random.choice("0123456789abcdef") for _ in range(length))
113
+
114
+
115
+ class _ChatHubRequest:
116
+ """
117
+ Request object for ChatHub
118
+ """
119
+
120
+ def __init__(
121
+ self,
122
+ conversation_signature: str,
123
+ client_id: str,
124
+ conversation_id: str,
125
+ invocation_id: int = 0,
126
+ ) -> None:
127
+ self.struct: dict = {}
128
+
129
+ self.client_id: str = client_id
130
+ self.conversation_id: str = conversation_id
131
+ self.conversation_signature: str = conversation_signature
132
+ self.invocation_id: int = invocation_id
133
+
134
+ def update(
135
+ self,
136
+ prompt,
137
+ conversation_style,
138
+ options,
139
+ ) -> None:
140
+ """
141
+ Updates request object
142
+ """
143
+ if options is None:
144
+ options = [
145
+ "deepleo",
146
+ "enable_debug_commands",
147
+ "disable_emoji_spoken_text",
148
+ "enablemm",
149
+ ]
150
+ if conversation_style:
151
+ if not isinstance(conversation_style, ConversationStyle):
152
+ conversation_style = getattr(ConversationStyle, conversation_style)
153
+ options = [
154
+ "nlu_direct_response_filter",
155
+ "deepleo",
156
+ "disable_emoji_spoken_text",
157
+ "responsible_ai_policy_235",
158
+ "enablemm",
159
+ conversation_style.value,
160
+ "dtappid",
161
+ "cricinfo",
162
+ "cricinfov2",
163
+ "dv3sugg",
164
+ ]
165
+ self.struct = {
166
+ "arguments": [
167
+ {
168
+ "source": "cib",
169
+ "optionsSets": options,
170
+ "sliceIds": [
171
+ "222dtappid",
172
+ "225cricinfo",
173
+ "224locals0",
174
+ ],
175
+ "traceId": _get_ran_hex(32),
176
+ "isStartOfSession": self.invocation_id == 0,
177
+ "message": {
178
+ "author": "user",
179
+ "inputMethod": "Keyboard",
180
+ "text": prompt,
181
+ "messageType": "Chat",
182
+ },
183
+ "conversationSignature": self.conversation_signature,
184
+ "participant": {
185
+ "id": self.client_id,
186
+ },
187
+ "conversationId": self.conversation_id,
188
+ },
189
+ ],
190
+ "invocationId": str(self.invocation_id),
191
+ "target": "chat",
192
+ "type": 4,
193
+ }
194
+ self.invocation_id += 1
195
+
196
+
197
+ class _Conversation:
198
+ """
199
+ Conversation API
200
+ """
201
+
202
+ def __init__(
203
+ self,
204
+ cookies,
205
+ proxy,
206
+ ) -> None:
207
+ self.struct: dict = {
208
+ "conversationId": None,
209
+ "clientId": None,
210
+ "conversationSignature": None,
211
+ "result": {"value": "Success", "message": None},
212
+ }
213
+ self.proxy = proxy
214
+ proxy = (
215
+ proxy
216
+ or os.environ.get("all_proxy")
217
+ or os.environ.get("ALL_PROXY")
218
+ or os.environ.get("https_proxy")
219
+ or os.environ.get("HTTPS_PROXY")
220
+ or None
221
+ )
222
+ if proxy is not None and proxy.startswith("socks5h://"):
223
+ proxy = "socks5://" + proxy[len("socks5h://") :]
224
+ self.session = httpx.Client(
225
+ proxies=proxy,
226
+ timeout=30,
227
+ headers=HEADERS_INIT_CONVER,
228
+ )
229
+ for cookie in cookies:
230
+ self.session.cookies.set(cookie["name"], cookie["value"])
231
+
232
+ # Send GET request
233
+ response = self.session.get(
234
+ url=os.environ.get("BING_PROXY_URL")
235
+ or "https://edgeservices.bing.com/edgesvc/turing/conversation/create",
236
+ )
237
+ if response.status_code != 200:
238
+ response = self.session.get(
239
+ "https://edge.churchless.tech/edgesvc/turing/conversation/create",
240
+ )
241
+ if response.status_code != 200:
242
+ print(f"Status code: {response.status_code}")
243
+ print(response.text)
244
+ print(response.url)
245
+ raise Exception("Authentication failed")
246
+ try:
247
+ self.struct = response.json()
248
+ except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc:
249
+ raise Exception(
250
+ "Authentication failed. You have not been accepted into the beta.",
251
+ ) from exc
252
+ if self.struct["result"]["value"] == "UnauthorizedRequest":
253
+ raise NotAllowedToAccess(self.struct["result"]["message"])
254
+
255
+
256
+ class _ChatHub:
257
+ """
258
+ Chat API
259
+ """
260
+
261
+ def __init__(self, conversation) -> None:
262
+ self.wss = None
263
+ self.request: _ChatHubRequest
264
+ self.loop: bool
265
+ self.task: asyncio.Task
266
+ print(conversation.struct)
267
+ self.request = _ChatHubRequest(
268
+ conversation_signature=conversation.struct["conversationSignature"],
269
+ client_id=conversation.struct["clientId"],
270
+ conversation_id=conversation.struct["conversationId"],
271
+ )
272
+
273
+ async def ask_stream(
274
+ self,
275
+ prompt: str,
276
+ wss_link: str,
277
+ conversation_style: CONVERSATION_STYLE_TYPE = None,
278
+ raw: bool = False,
279
+ options: dict = None,
280
+ ) -> Generator[str, None, None]:
281
+ """
282
+ Ask a question to the bot
283
+ """
284
+ if self.wss and not self.wss.closed:
285
+ await self.wss.close()
286
+ # Check if websocket is closed
287
+ self.wss = await websockets.connect(
288
+ wss_link,
289
+ extra_headers=HEADERS,
290
+ max_size=None,
291
+ ssl=ssl_context,
292
+ )
293
+ await self._initial_handshake()
294
+ # Construct a ChatHub request
295
+ self.request.update(
296
+ prompt=prompt,
297
+ conversation_style=conversation_style,
298
+ options=options,
299
+ )
300
+ # Send request
301
+ await self.wss.send(_append_identifier(self.request.struct))
302
+ final = False
303
+ while not final:
304
+ objects = str(await self.wss.recv()).split(DELIMITER)
305
+ for obj in objects:
306
+ if obj is None or not obj:
307
+ continue
308
+ response = json.loads(obj)
309
+ if response.get("type") != 2 and raw:
310
+ yield False, response
311
+ elif response.get("type") == 1 and response["arguments"][0].get(
312
+ "messages",
313
+ ):
314
+ resp_txt = response["arguments"][0]["messages"][0]["adaptiveCards"][
315
+ 0
316
+ ]["body"][0].get("text")
317
+ yield False, resp_txt
318
+ elif response.get("type") == 2:
319
+ final = True
320
+ yield True, response
321
+
322
+ async def _initial_handshake(self) -> None:
323
+ await self.wss.send(_append_identifier({"protocol": "json", "version": 1}))
324
+ await self.wss.recv()
325
+
326
+ async def close(self) -> None:
327
+ """
328
+ Close the connection
329
+ """
330
+ if self.wss and not self.wss.closed:
331
+ await self.wss.close()
332
+
333
+
334
+ class NewbingChatbot:
335
+ """
336
+ Combines everything to make it seamless
337
+ """
338
+
339
+ def __init__(
340
+ self,
341
+ cookies,
342
+ proxy
343
+ ) -> None:
344
+ if cookies is None:
345
+ cookies = {}
346
+ self.cookies = cookies
347
+ self.proxy = proxy
348
+ self.chat_hub: _ChatHub = _ChatHub(
349
+ _Conversation(self.cookies, self.proxy),
350
+ )
351
+
352
+ async def ask(
353
+ self,
354
+ prompt: str,
355
+ wss_link: str,
356
+ conversation_style: CONVERSATION_STYLE_TYPE = None,
357
+ options: dict = None,
358
+ ) -> dict:
359
+ """
360
+ Ask a question to the bot
361
+ """
362
+ async for final, response in self.chat_hub.ask_stream(
363
+ prompt=prompt,
364
+ conversation_style=conversation_style,
365
+ wss_link=wss_link,
366
+ options=options,
367
+ ):
368
+ if final:
369
+ return response
370
+ await self.chat_hub.wss.close()
371
+ return None
372
+
373
+ async def ask_stream(
374
+ self,
375
+ prompt: str,
376
+ wss_link: str,
377
+ conversation_style: CONVERSATION_STYLE_TYPE = None,
378
+ raw: bool = False,
379
+ options: dict = None,
380
+ ) -> Generator[str, None, None]:
381
+ """
382
+ Ask a question to the bot
383
+ """
384
+ async for response in self.chat_hub.ask_stream(
385
+ prompt=prompt,
386
+ conversation_style=conversation_style,
387
+ wss_link=wss_link,
388
+ raw=raw,
389
+ options=options,
390
+ ):
391
+ yield response
392
+
393
+ async def close(self) -> None:
394
+ """
395
+ Close the connection
396
+ """
397
+ await self.chat_hub.close()
398
+
399
+ async def reset(self) -> None:
400
+ """
401
+ Reset the conversation
402
+ """
403
+ await self.close()
404
+ self.chat_hub = _ChatHub(_Conversation(self.cookies, self.proxy))
405
+
406
+