xiaolv commited on
Commit
e258c8a
1 Parent(s): 4739d7c

Delete EdgeGPT.py

Browse files
Files changed (1) hide show
  1. EdgeGPT.py +0 -883
EdgeGPT.py DELETED
@@ -1,883 +0,0 @@
1
- """
2
- Main.py
3
- """
4
- from __future__ import annotations
5
-
6
- import argparse
7
- import asyncio
8
- import json
9
- import os
10
- import random
11
- import re
12
- import ssl
13
- import sys
14
- import uuid
15
- from enum import Enum
16
- from pathlib import Path
17
- from typing import Generator
18
- from typing import Literal
19
- from typing import Optional
20
- from typing import Union
21
-
22
- import certifi
23
- import httpx
24
- import websockets.client as websockets
25
- from BingImageCreator import ImageGenAsync
26
- from prompt_toolkit import PromptSession
27
- from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
28
- from prompt_toolkit.completion import WordCompleter
29
- from prompt_toolkit.history import InMemoryHistory
30
- from prompt_toolkit.key_binding import KeyBindings
31
- from rich.live import Live
32
- from rich.markdown import Markdown
33
-
34
- DELIMITER = "\x1e"
35
-
36
-
37
- # Generate random IP between range 13.104.0.0/14
38
- FORWARDED_IP = (
39
- f"13.{random.randint(104, 107)}.{random.randint(0, 255)}.{random.randint(0, 255)}"
40
- )
41
-
42
- HEADERS = {
43
- "accept": "application/json",
44
- "accept-language": "en-US,en;q=0.9",
45
- "content-type": "application/json",
46
- "sec-ch-ua": '"Not_A Brand";v="99", "Microsoft Edge";v="110", "Chromium";v="110"',
47
- "sec-ch-ua-arch": '"x86"',
48
- "sec-ch-ua-bitness": '"64"',
49
- "sec-ch-ua-full-version": '"109.0.1518.78"',
50
- "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"',
51
- "sec-ch-ua-mobile": "?0",
52
- "sec-ch-ua-model": "",
53
- "sec-ch-ua-platform": '"Windows"',
54
- "sec-ch-ua-platform-version": '"15.0.0"',
55
- "sec-fetch-dest": "empty",
56
- "sec-fetch-mode": "cors",
57
- "sec-fetch-site": "same-origin",
58
- "x-ms-client-request-id": str(uuid.uuid4()),
59
- "x-ms-useragent": "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Win32",
60
- "Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx",
61
- "Referrer-Policy": "origin-when-cross-origin",
62
- "x-forwarded-for": FORWARDED_IP,
63
- }
64
-
65
- HEADERS_INIT_CONVER = {
66
- "authority": "edgeservices.bing.com",
67
- "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",
68
- "accept-language": "en-US,en;q=0.9",
69
- "cache-control": "max-age=0",
70
- "sec-ch-ua": '"Chromium";v="110", "Not A(Brand";v="24", "Microsoft Edge";v="110"',
71
- "sec-ch-ua-arch": '"x86"',
72
- "sec-ch-ua-bitness": '"64"',
73
- "sec-ch-ua-full-version": '"110.0.1587.69"',
74
- "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"',
75
- "sec-ch-ua-mobile": "?0",
76
- "sec-ch-ua-model": '""',
77
- "sec-ch-ua-platform": '"Windows"',
78
- "sec-ch-ua-platform-version": '"15.0.0"',
79
- "sec-fetch-dest": "document",
80
- "sec-fetch-mode": "navigate",
81
- "sec-fetch-site": "none",
82
- "sec-fetch-user": "?1",
83
- "upgrade-insecure-requests": "1",
84
- "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",
85
- "x-edge-shopping-flag": "1",
86
- "x-forwarded-for": FORWARDED_IP,
87
- }
88
-
89
- ssl_context = ssl.create_default_context()
90
- ssl_context.load_verify_locations(certifi.where())
91
-
92
-
93
- class NotAllowedToAccess(Exception):
94
- pass
95
-
96
-
97
- class ConversationStyle(Enum):
98
- creative = [
99
- "nlu_direct_response_filter",
100
- "deepleo",
101
- "disable_emoji_spoken_text",
102
- "responsible_ai_policy_235",
103
- "enablemm",
104
- "h3imaginative",
105
- "travelansgnd",
106
- "dv3sugg",
107
- "clgalileo",
108
- "gencontentv3",
109
- "dv3sugg",
110
- "responseos",
111
- "e2ecachewrite",
112
- "cachewriteext",
113
- "nodlcpcwrite",
114
- "travelansgnd",
115
- "nojbfedge",
116
- ]
117
- balanced = [
118
- "nlu_direct_response_filter",
119
- "deepleo",
120
- "disable_emoji_spoken_text",
121
- "responsible_ai_policy_235",
122
- "enablemm",
123
- "galileo",
124
- "dv3sugg",
125
- "responseos",
126
- "e2ecachewrite",
127
- "cachewriteext",
128
- "nodlcpcwrite",
129
- "travelansgnd",
130
- "nojbfedge",
131
- ]
132
- precise = [
133
- "nlu_direct_response_filter",
134
- "deepleo",
135
- "disable_emoji_spoken_text",
136
- "responsible_ai_policy_235",
137
- "enablemm",
138
- "galileo",
139
- "dv3sugg",
140
- "responseos",
141
- "e2ecachewrite",
142
- "cachewriteext",
143
- "nodlcpcwrite",
144
- "travelansgnd",
145
- "h3precise",
146
- "clgalileo",
147
- "nojbfedge",
148
- ]
149
-
150
-
151
- CONVERSATION_STYLE_TYPE = Optional[
152
- Union[ConversationStyle, Literal["creative", "balanced", "precise"]]
153
- ]
154
-
155
-
156
- def _append_identifier(msg: dict) -> str:
157
- """
158
- Appends special character to end of message to identify end of message
159
- """
160
- # Convert dict to json string
161
- return json.dumps(msg, ensure_ascii=False) + DELIMITER
162
-
163
-
164
- def _get_ran_hex(length: int = 32) -> str:
165
- """
166
- Returns random hex string
167
- """
168
- return "".join(random.choice("0123456789abcdef") for _ in range(length))
169
-
170
-
171
- class _ChatHubRequest:
172
- """
173
- Request object for ChatHub
174
- """
175
-
176
- def __init__(
177
- self,
178
- conversation_signature: str,
179
- client_id: str,
180
- conversation_id: str,
181
- invocation_id: int = 0,
182
- ) -> None:
183
- self.struct: dict = {}
184
-
185
- self.client_id: str = client_id
186
- self.conversation_id: str = conversation_id
187
- self.conversation_signature: str = conversation_signature
188
- self.invocation_id: int = invocation_id
189
-
190
- def update(
191
- self,
192
- prompt: str,
193
- conversation_style: CONVERSATION_STYLE_TYPE,
194
- options: list | None = None,
195
- webpage_context: str | None = None,
196
- search_result: bool = False,
197
- ) -> None:
198
- """
199
- Updates request object
200
- """
201
- if options is None:
202
- options = [
203
- "deepleo",
204
- "enable_debug_commands",
205
- "disable_emoji_spoken_text",
206
- "enablemm",
207
- ]
208
- if conversation_style:
209
- if not isinstance(conversation_style, ConversationStyle):
210
- conversation_style = getattr(ConversationStyle, conversation_style)
211
- options = conversation_style.value
212
- self.struct = {
213
- "arguments": [
214
- {
215
- "source": "cib",
216
- "optionsSets": options,
217
- "allowedMessageTypes": [
218
- "Chat",
219
- "Disengaged",
220
- "AdsQuery",
221
- "SemanticSerp",
222
- "GenerateContentQuery",
223
- "SearchQuery",
224
- ],
225
- "sliceIds": [
226
- "chk1cf",
227
- "nopreloadsscf",
228
- "winlongmsg2tf",
229
- "perfimpcomb",
230
- "sugdivdis",
231
- "sydnoinputt",
232
- "wpcssopt",
233
- "wintone2tf",
234
- "0404sydicnbs0",
235
- "405suggbs0",
236
- "scctl",
237
- "330uaugs0",
238
- "0329resp",
239
- "udscahrfon",
240
- "udstrblm5",
241
- "404e2ewrt",
242
- "408nodedups0",
243
- "403tvlansgnd",
244
- ],
245
- "traceId": _get_ran_hex(32),
246
- "isStartOfSession": self.invocation_id == 0,
247
- "message": {
248
- "author": "user",
249
- "inputMethod": "Keyboard",
250
- "text": prompt,
251
- "messageType": "Chat",
252
- },
253
- "conversationSignature": self.conversation_signature,
254
- "participant": {
255
- "id": self.client_id,
256
- },
257
- "conversationId": self.conversation_id,
258
- },
259
- ],
260
- "invocationId": str(self.invocation_id),
261
- "target": "chat",
262
- "type": 4,
263
- }
264
- if search_result:
265
- have_search_result = [
266
- "InternalSearchQuery",
267
- "InternalSearchResult",
268
- "InternalLoaderMessage",
269
- "RenderCardRequest",
270
- ]
271
- self.struct["arguments"][0]["allowedMessageTypes"] += have_search_result
272
- if webpage_context:
273
- self.struct["arguments"][0]["previousMessages"] = [
274
- {
275
- "author": "user",
276
- "description": webpage_context,
277
- "contextType": "WebPage",
278
- "messageType": "Context",
279
- "messageId": "discover-web--page-ping-mriduna-----",
280
- },
281
- ]
282
- self.invocation_id += 1
283
-
284
-
285
- class _Conversation:
286
- """
287
- Conversation API
288
- """
289
-
290
- def __init__(
291
- self,
292
- cookies: dict | None = None,
293
- proxy: str | None = None,
294
- async_mode: bool = False,
295
- ) -> None:
296
- if async_mode:
297
- return
298
- self.struct: dict = {
299
- "conversationId": None,
300
- "clientId": None,
301
- "conversationSignature": None,
302
- "result": {"value": "Success", "message": None},
303
- }
304
- self.proxy = proxy
305
- proxy = (
306
- proxy
307
- or os.environ.get("all_proxy")
308
- or os.environ.get("ALL_PROXY")
309
- or os.environ.get("https_proxy")
310
- or os.environ.get("HTTPS_PROXY")
311
- or None
312
- )
313
- if proxy is not None and proxy.startswith("socks5h://"):
314
- proxy = "socks5://" + proxy[len("socks5h://") :]
315
- self.session = httpx.Client(
316
- proxies=proxy,
317
- timeout=300,
318
- headers=HEADERS_INIT_CONVER,
319
- )
320
- for cookie in cookies:
321
- self.session.cookies.set(cookie["name"], cookie["value"])
322
-
323
- # Send GET request
324
- response = self.session.get(
325
- url=os.environ.get("BING_PROXY_URL")
326
- or "https://edgeservices.bing.com/edgesvc/turing/conversation/create",
327
- )
328
- if response.status_code != 200:
329
- response = self.session.get(
330
- "https://edge.churchless.tech/edgesvc/turing/conversation/create",
331
- )
332
- if response.status_code != 200:
333
- print(f"Status code: {response.status_code}")
334
- print(response.text)
335
- print(response.url)
336
- raise Exception("Authentication failed")
337
- try:
338
- self.struct = response.json()
339
- except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc:
340
- raise Exception(
341
- "Authentication failed. You have not been accepted into the beta.",
342
- ) from exc
343
- if self.struct["result"]["value"] == "UnauthorizedRequest":
344
- raise NotAllowedToAccess(self.struct["result"]["message"])
345
-
346
- @staticmethod
347
- async def create(
348
- cookies: dict,
349
- proxy: str | None = None,
350
- ) -> _Conversation:
351
- self = _Conversation(async_mode=True)
352
- self.struct = {
353
- "conversationId": None,
354
- "clientId": None,
355
- "conversationSignature": None,
356
- "result": {"value": "Success", "message": None},
357
- }
358
- self.proxy = proxy
359
- proxy = (
360
- proxy
361
- or os.environ.get("all_proxy")
362
- or os.environ.get("ALL_PROXY")
363
- or os.environ.get("https_proxy")
364
- or os.environ.get("HTTPS_PROXY")
365
- or None
366
- )
367
- if proxy is not None and proxy.startswith("socks5h://"):
368
- proxy = "socks5://" + proxy[len("socks5h://") :]
369
- transport = httpx.AsyncHTTPTransport(retries=10)
370
- async with httpx.AsyncClient(
371
- proxies=proxy,
372
- timeout=300,
373
- headers=HEADERS_INIT_CONVER,
374
- transport=transport,
375
- ) as client:
376
- for cookie in cookies:
377
- client.cookies.set(cookie["name"], cookie["value"])
378
-
379
- # Send GET request
380
- response = await client.get(
381
- url=os.environ.get("BING_PROXY_URL")
382
- or "https://edgeservices.bing.com/edgesvc/turing/conversation/create",
383
- )
384
- if response.status_code != 200:
385
- response = await client.get(
386
- "https://edge.churchless.tech/edgesvc/turing/conversation/create",
387
- )
388
- if response.status_code != 200:
389
- print(f"Status code: {response.status_code}")
390
- print(response.text)
391
- print(response.url)
392
- raise Exception("Authentication failed")
393
- try:
394
- self.struct = response.json()
395
- except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc:
396
- raise Exception(
397
- "Authentication failed. You have not been accepted into the beta.",
398
- ) from exc
399
- if self.struct["result"]["value"] == "UnauthorizedRequest":
400
- raise NotAllowedToAccess(self.struct["result"]["message"])
401
- return self
402
-
403
-
404
- class _ChatHub:
405
- """
406
- Chat API
407
- """
408
-
409
- def __init__(self, conversation: _Conversation) -> None:
410
- self.wss: websockets.WebSocketClientProtocol | None = None
411
- self.request: _ChatHubRequest
412
- self.loop: bool
413
- self.task: asyncio.Task
414
- self.request = _ChatHubRequest(
415
- conversation_signature=conversation.struct["conversationSignature"],
416
- client_id=conversation.struct["clientId"],
417
- conversation_id=conversation.struct["conversationId"],
418
- )
419
-
420
- async def ask_stream(
421
- self,
422
- prompt: str,
423
- wss_link: str,
424
- cookies: str,
425
- conversation_style: CONVERSATION_STYLE_TYPE = None,
426
- raw: bool = False,
427
- options: dict = None,
428
- webpage_context: str | None = None,
429
- search_result: bool = False,
430
- ) -> Generator[str, None, None]:
431
- """
432
- Ask a question to the bot
433
- """
434
- if self.wss and not self.wss.closed:
435
- await self.wss.close()
436
- # Check if websocket is closed
437
- self.wss = await websockets.connect(
438
- wss_link,
439
- extra_headers=HEADERS,
440
- max_size=None,
441
- ssl=ssl_context,
442
- )
443
- await self._initial_handshake()
444
- if self.request.invocation_id == 0:
445
- # Construct a ChatHub request
446
- self.request.update(
447
- prompt=prompt,
448
- conversation_style=conversation_style,
449
- options=options,
450
- webpage_context=webpage_context,
451
- search_result=search_result,
452
- )
453
- else:
454
- async with httpx.AsyncClient() as client:
455
- response = await client.post(
456
- "https://sydney.bing.com/sydney/UpdateConversation/",
457
- json={
458
- "messages": [
459
- {
460
- "author": "user",
461
- "description": webpage_context,
462
- "contextType": "WebPage",
463
- "messageType": "Context",
464
- },
465
- ],
466
- "conversationId": self.request.conversation_id,
467
- "source": "cib",
468
- "traceId": _get_ran_hex(32),
469
- "participant": {"id": self.request.client_id},
470
- "conversationSignature": self.request.conversation_signature,
471
- },
472
- )
473
- if response.status_code != 200:
474
- print(f"Status code: {response.status_code}")
475
- print(response.text)
476
- print(response.url)
477
- raise Exception("Update web page context failed")
478
- # Construct a ChatHub request
479
- self.request.update(
480
- prompt=prompt,
481
- conversation_style=conversation_style,
482
- options=options,
483
- )
484
- # Send request
485
- await self.wss.send(_append_identifier(self.request.struct))
486
- final = False
487
- draw = False
488
- resp_txt = ""
489
- result_text = ""
490
- resp_txt_no_link = ""
491
- while not final:
492
- objects = str(await self.wss.recv()).split(DELIMITER)
493
- for obj in objects:
494
- if obj is None or not obj:
495
- continue
496
- response = json.loads(obj)
497
- if response.get("type") != 2 and raw:
498
- yield False, response
499
- elif response.get("type") == 1 and response["arguments"][0].get(
500
- "messages",
501
- ):
502
- if not draw:
503
- if (
504
- response["arguments"][0]["messages"][0].get("messageType")
505
- == "GenerateContentQuery"
506
- ):
507
- for item in cookies:
508
- if item["name"] == "_U":
509
- U = item["value"]
510
- async with ImageGenAsync(U, True) as image_generator:
511
- images = await image_generator.get_images(
512
- response["arguments"][0]["messages"][0]["text"],
513
- )
514
- for i, image in enumerate(images):
515
- resp_txt = resp_txt + f"\n![image{i}]({image})"
516
- draw = True
517
- if (
518
- response["arguments"][0]["messages"][0]["contentOrigin"]
519
- != "Apology"
520
- ) and not draw:
521
- resp_txt = result_text + response["arguments"][0][
522
- "messages"
523
- ][0]["adaptiveCards"][0]["body"][0].get("text", "")
524
- resp_txt_no_link = result_text + response["arguments"][0][
525
- "messages"
526
- ][0].get("text", "")
527
- if response["arguments"][0]["messages"][0].get(
528
- "messageType",
529
- ):
530
- resp_txt = (
531
- resp_txt
532
- + response["arguments"][0]["messages"][0][
533
- "adaptiveCards"
534
- ][0]["body"][0]["inlines"][0].get("text")
535
- + "\n"
536
- )
537
- result_text = (
538
- result_text
539
- + response["arguments"][0]["messages"][0][
540
- "adaptiveCards"
541
- ][0]["body"][0]["inlines"][0].get("text")
542
- + "\n"
543
- )
544
- yield False, resp_txt
545
-
546
- elif response.get("type") == 2:
547
- if draw:
548
- cache = response["item"]["messages"][1]["adaptiveCards"][0][
549
- "body"
550
- ][0]["text"]
551
- response["item"]["messages"][1]["adaptiveCards"][0]["body"][0][
552
- "text"
553
- ] = (cache + resp_txt)
554
- if (
555
- response["item"]["messages"][-1]["contentOrigin"] == "Apology"
556
- and resp_txt
557
- ):
558
- response["item"]["messages"][-1]["text"] = resp_txt_no_link
559
- response["item"]["messages"][-1]["adaptiveCards"][0]["body"][0][
560
- "text"
561
- ] = resp_txt
562
- print(
563
- "Preserved the message from being deleted",
564
- file=sys.stderr,
565
- )
566
- final = True
567
- yield True, response
568
-
569
- async def _initial_handshake(self) -> None:
570
- await self.wss.send(_append_identifier({"protocol": "json", "version": 1}))
571
- await self.wss.recv()
572
-
573
- async def close(self) -> None:
574
- """
575
- Close the connection
576
- """
577
- if self.wss and not self.wss.closed:
578
- await self.wss.close()
579
-
580
-
581
- class Chatbot:
582
- """
583
- Combines everything to make it seamless
584
- """
585
-
586
- def __init__(
587
- self,
588
- cookies: dict = None,
589
- proxy: str | None = None,
590
- cookie_path: str = None,
591
- ) -> None:
592
- if cookies is None:
593
- cookies = {}
594
- if cookie_path is not None:
595
- try:
596
- with open(cookie_path, encoding="utf-8") as f:
597
- self.cookies = json.load(f)
598
- except FileNotFoundError as exc:
599
- raise FileNotFoundError("Cookie file not found") from exc
600
- else:
601
- self.cookies = cookies
602
- self.proxy: str | None = proxy
603
- self.chat_hub: _ChatHub = _ChatHub(
604
- _Conversation(self.cookies, self.proxy),
605
- )
606
- print(f"*" * 100)
607
- print(f">>>>>>> 执行了小吕自己的本地代码")
608
- print(f"*" * 100)
609
-
610
- @staticmethod
611
- async def create(
612
- cookies: dict = None,
613
- proxy: str | None = None,
614
- cookie_path: str = None,
615
- ):
616
- self = Chatbot.__new__(Chatbot)
617
- if cookies is None:
618
- cookies = {}
619
- if cookie_path is not None:
620
- try:
621
- with open(cookie_path, encoding="utf-8") as f:
622
- self.cookies = json.load(f)
623
- except FileNotFoundError as exc:
624
- raise FileNotFoundError("Cookie file not found") from exc
625
- else:
626
- self.cookies = cookies
627
- self.proxy = proxy
628
- self.chat_hub = _ChatHub(
629
- await _Conversation.create(self.cookies, self.proxy),
630
- )
631
- return self
632
-
633
- async def ask(
634
- self,
635
- prompt: str,
636
- wss_link: str = "wss://sydney.bing.com/sydney/ChatHub",
637
- conversation_style: CONVERSATION_STYLE_TYPE = None,
638
- options: dict = None,
639
- webpage_context: str | None = None,
640
- search_result: bool = False,
641
- ) -> dict:
642
- """
643
- Ask a question to the bot
644
- """
645
- async for final, response in self.chat_hub.ask_stream(
646
- prompt=prompt,
647
- conversation_style=conversation_style,
648
- wss_link=wss_link,
649
- options=options,
650
- cookies=self.cookies,
651
- webpage_context=webpage_context,
652
- search_result=search_result,
653
- ):
654
- if final:
655
- return response
656
- await self.chat_hub.wss.close()
657
- return {}
658
-
659
- async def ask_stream(
660
- self,
661
- prompt: str,
662
- wss_link: str = "wss://sydney.bing.com/sydney/ChatHub",
663
- conversation_style: CONVERSATION_STYLE_TYPE = None,
664
- raw: bool = False,
665
- options: dict = None,
666
- webpage_context: str | None = None,
667
- search_result: bool = False,
668
- ) -> Generator[str, None, None]:
669
- """
670
- Ask a question to the bot
671
- """
672
- async for response in self.chat_hub.ask_stream(
673
- prompt=prompt,
674
- conversation_style=conversation_style,
675
- wss_link=wss_link,
676
- raw=raw,
677
- options=options,
678
- cookies=self.cookies,
679
- webpage_context=webpage_context,
680
- search_result=search_result,
681
- ):
682
- yield response
683
-
684
- async def close(self) -> None:
685
- """
686
- Close the connection
687
- """
688
- await self.chat_hub.close()
689
-
690
- async def reset(self) -> None:
691
- """
692
- Reset the conversation
693
- """
694
- await self.close()
695
- self.chat_hub = _ChatHub(
696
- await _Conversation.create(self.cookies, self.proxy),
697
- )
698
-
699
-
700
- async def _get_input_async(
701
- session: PromptSession = None,
702
- completer: WordCompleter = None,
703
- ) -> str:
704
- """
705
- Multiline input function.
706
- """
707
- return await session.prompt_async(
708
- completer=completer,
709
- multiline=True,
710
- auto_suggest=AutoSuggestFromHistory(),
711
- )
712
-
713
-
714
- def _create_session() -> PromptSession:
715
- kb = KeyBindings()
716
-
717
- @kb.add("enter")
718
- def _(event):
719
- buffer_text = event.current_buffer.text
720
- if buffer_text.startswith("!"):
721
- event.current_buffer.validate_and_handle()
722
- else:
723
- event.current_buffer.insert_text("\n")
724
-
725
- @kb.add("escape")
726
- def _(event):
727
- if event.current_buffer.complete_state:
728
- # event.current_buffer.cancel_completion()
729
- event.current_buffer.text = ""
730
-
731
- return PromptSession(key_bindings=kb, history=InMemoryHistory())
732
-
733
-
734
- def _create_completer(commands: list, pattern_str: str = "$"):
735
- return WordCompleter(words=commands, pattern=re.compile(pattern_str))
736
-
737
-
738
- async def async_main(args: argparse.Namespace) -> None:
739
- """
740
- Main function
741
- """
742
- print("Initializing...")
743
- print("Enter `alt+enter` or `escape+enter` to send a message")
744
- bot = await Chatbot.create(proxy=args.proxy, cookies=args.cookies)
745
- session = _create_session()
746
- completer = _create_completer(["!help", "!exit", "!reset"])
747
- initial_prompt = args.prompt
748
-
749
- while True:
750
- print("\nYou:")
751
- if initial_prompt:
752
- question = initial_prompt
753
- print(question)
754
- initial_prompt = None
755
- else:
756
- question = (
757
- input()
758
- if args.enter_once
759
- else await _get_input_async(session=session, completer=completer)
760
- )
761
- print()
762
- if question == "!exit":
763
- break
764
- if question == "!help":
765
- print(
766
- """
767
- !help - Show this help message
768
- !exit - Exit the program
769
- !reset - Reset the conversation
770
- """,
771
- )
772
- continue
773
- if question == "!reset":
774
- await bot.reset()
775
- continue
776
- print("Bot:")
777
- if args.no_stream:
778
- print(
779
- (
780
- await bot.ask(
781
- prompt=question,
782
- conversation_style=args.style,
783
- wss_link=args.wss_link,
784
- )
785
- )["item"]["messages"][1]["adaptiveCards"][0]["body"][0]["text"],
786
- )
787
- else:
788
- wrote = 0
789
- if args.rich:
790
- md = Markdown("")
791
- with Live(md, auto_refresh=False) as live:
792
- async for final, response in bot.ask_stream(
793
- prompt=question,
794
- conversation_style=args.style,
795
- wss_link=args.wss_link,
796
- ):
797
- if not final:
798
- if wrote > len(response):
799
- print(md)
800
- print(Markdown("***Bing revoked the response.***"))
801
- wrote = len(response)
802
- md = Markdown(response)
803
- live.update(md, refresh=True)
804
- else:
805
- async for final, response in bot.ask_stream(
806
- prompt=question,
807
- conversation_style=args.style,
808
- wss_link=args.wss_link,
809
- ):
810
- if not final:
811
- if not wrote:
812
- print(response, end="", flush=True)
813
- else:
814
- print(response[wrote:], end="", flush=True)
815
- wrote = len(response)
816
- print()
817
- await bot.close()
818
-
819
-
820
- def main() -> None:
821
- print(
822
- """
823
- EdgeGPT - A demo of reverse engineering the Bing GPT chatbot
824
- Repo: github.com/acheong08/EdgeGPT
825
- By: Antonio Cheong
826
-
827
- !help for help
828
-
829
- Type !exit to exit
830
- """,
831
- )
832
- parser = argparse.ArgumentParser()
833
- parser.add_argument("--enter-once", action="store_true")
834
- parser.add_argument("--no-stream", action="store_true")
835
- parser.add_argument("--rich", action="store_true")
836
- parser.add_argument(
837
- "--proxy",
838
- help="Proxy URL (e.g. socks5://127.0.0.1:1080)",
839
- type=str,
840
- )
841
- parser.add_argument(
842
- "--wss-link",
843
- help="WSS URL(e.g. wss://sydney.bing.com/sydney/ChatHub)",
844
- type=str,
845
- default="wss://sydney.bing.com/sydney/ChatHub",
846
- )
847
- parser.add_argument(
848
- "--style",
849
- choices=["creative", "balanced", "precise"],
850
- default="balanced",
851
- )
852
- parser.add_argument(
853
- "--cookie-file",
854
- type=str,
855
- default=os.environ.get("COOKIE_FILE", ""),
856
- required=False,
857
- help="Cookie file used for authentication (defaults to COOKIE_FILE environment variable)",
858
- )
859
- parser.add_argument(
860
- "--prompt",
861
- type=str,
862
- default="",
863
- required=False,
864
- help="prompt to start with",
865
- )
866
- args = parser.parse_args()
867
- if not args.cookie_file:
868
- parser.print_help()
869
- parser.exit(
870
- 1,
871
- "ERROR: use --cookie-file or set the COOKIE_FILE environment variable",
872
- )
873
- try:
874
- args.cookies = json.loads(Path(args.cookie_file).read_text(encoding="utf-8"))
875
- except OSError as exc:
876
- print(f"Could not open cookie file: {exc}", file=sys.stderr)
877
- sys.exit(1)
878
-
879
- asyncio.run(async_main(args))
880
-
881
-
882
- if __name__ == "__main__":
883
- main()