Antonio Cheong commited on
Commit
9f7a351
·
1 Parent(s): ef4de38

Initial working version

Browse files
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .env
main.py → BingGPT.py RENAMED
@@ -1,13 +1,13 @@
1
  """
2
  Main.py
3
  """
 
4
  import json
5
- import time
6
  import uuid
7
- from threading import Thread
8
 
 
9
  import requests
10
- from websocket import WebSocket
11
 
12
 
13
  def append_identifier(msg: dict) -> str:
@@ -28,7 +28,7 @@ class ChatHubRequest:
28
  conversation_signature: str,
29
  client_id: str,
30
  conversation_id: str,
31
- invocation_id: int,
32
  ) -> None:
33
  self.struct: dict
34
 
@@ -36,23 +36,10 @@ class ChatHubRequest:
36
  self.conversation_id: str = conversation_id
37
  self.conversation_signature: str = conversation_signature
38
  self.invocation_id: int = invocation_id
39
- self.is_start_of_session: bool = True
40
-
41
- self.update(
42
- prompt=None,
43
- conversation_signature=conversation_signature,
44
- client_id=client_id,
45
- conversation_id=conversation_id,
46
- invocation_id=invocation_id,
47
- )
48
 
49
  def update(
50
  self,
51
  prompt: str,
52
- conversation_signature: str = None,
53
- client_id: str = None,
54
- conversation_id: str = None,
55
- invocation_id: int = None,
56
  ) -> None:
57
  """
58
  Updates request object
@@ -69,26 +56,25 @@ class ChatHubRequest:
69
  "responsible_ai_policy_235",
70
  "enablemm",
71
  ],
72
- "isStartOfSession": self.is_start_of_session,
73
  "message": {
74
- "timestamp": "2023-02-09T13:26:58+08:00",
75
  "author": "user",
76
  "inputMethod": "Keyboard",
77
  "text": prompt,
78
  "messageType": "Chat",
79
  },
80
- "conversationSignature": conversation_signature
81
- or self.conversation_signature,
82
- "participant": {"id": client_id or self.client_id},
83
- "conversationId": conversation_id or self.conversation_id,
84
- "previousMessages": [],
85
- },
86
  ],
87
- "invocationId": str(invocation_id),
88
  "target": "chat",
89
  "type": 4,
90
  }
91
- self.is_start_of_session = False
92
 
93
 
94
  class Conversation:
@@ -103,9 +89,6 @@ class Conversation:
103
  "conversationSignature": None,
104
  "result": {"value": "Success", "message": None},
105
  }
106
- self.__create()
107
-
108
- def __create(self):
109
  # Build request
110
  headers = {
111
  "accept": "application/json",
@@ -129,9 +112,9 @@ class Conversation:
129
  "x-ms-useragent": "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Linuxx86_64",
130
  }
131
  # Create cookies
132
- cookies = json.loads(
133
- open("templates/cookies.json", encoding="utf-8").read(),
134
- )
135
  # Send GET request
136
  response = requests.get(
137
  "https://www.bing.com/turing/conversation/create",
@@ -139,65 +122,112 @@ class Conversation:
139
  cookies=cookies,
140
  timeout=30,
141
  )
 
 
142
  # Return response
143
  self.struct = response.json()
144
 
145
-
146
  class ChatHub:
147
  """
148
  Chat API
149
  """
150
 
151
  def __init__(self) -> None:
152
- self.wss = WebSocket()
153
- self.wss.connect(url="wss://sydney.bing.com/sydney/ChatHub")
154
- self.__initial_handshake()
155
- # Ping in another thread
156
- self.thread = Thread(target=self.__ping)
157
- self.thread.start()
158
- self.stop_thread = False
159
-
160
- def ask(self, prompt: str):
161
- pass
162
-
163
- def __initial_handshake(self):
164
- self.wss.send(append_identifier({"protocol": "json", "version": 1}))
165
- # Receive blank message
166
- self.wss.recv()
167
-
168
- def __ping(self):
169
- timing = 10
 
 
 
 
 
 
 
 
 
 
 
170
  while True:
171
- if timing == 0:
172
- self.wss.send(append_identifier({"type": 6}))
173
- # Receive pong
174
- self.wss.recv()
175
- timing = 10
176
- else:
177
- timing -= 1
178
- time.sleep(1)
179
- if self.stop_thread:
 
 
 
 
 
 
 
 
180
  break
181
-
182
- def close(self):
 
183
  """
184
- Close all connections
185
  """
186
- self.wss.close()
187
- self.stop_thread = True
188
- self.thread.join()
189
 
190
 
191
- async def main():
192
  """
193
- Main function
194
  """
195
- # Create conversation
196
- conversation = Conversation()
197
- print(conversation.struct)
 
 
 
 
 
 
 
198
 
 
 
 
 
 
 
 
 
 
 
199
 
200
- if __name__ == "__main__":
201
- import asyncio
202
 
 
 
 
 
 
 
 
 
 
 
 
203
  asyncio.run(main())
 
1
  """
2
  Main.py
3
  """
4
+ import os
5
  import json
 
6
  import uuid
 
7
 
8
+ import asyncio
9
  import requests
10
+ import websockets.client as websockets
11
 
12
 
13
  def append_identifier(msg: dict) -> str:
 
28
  conversation_signature: str,
29
  client_id: str,
30
  conversation_id: str,
31
+ invocation_id: int = 0,
32
  ) -> None:
33
  self.struct: dict
34
 
 
36
  self.conversation_id: str = conversation_id
37
  self.conversation_signature: str = conversation_signature
38
  self.invocation_id: int = invocation_id
 
 
 
 
 
 
 
 
 
39
 
40
  def update(
41
  self,
42
  prompt: str,
 
 
 
 
43
  ) -> None:
44
  """
45
  Updates request object
 
56
  "responsible_ai_policy_235",
57
  "enablemm",
58
  ],
59
+ "isStartOfSession": self.invocation_id == 0,
60
  "message": {
 
61
  "author": "user",
62
  "inputMethod": "Keyboard",
63
  "text": prompt,
64
  "messageType": "Chat",
65
  },
66
+ "conversationSignature": self.conversation_signature,
67
+ "participant": {
68
+ "id": self.client_id,
69
+ },
70
+ "conversationId": self.conversation_id,
71
+ }
72
  ],
73
+ "invocationId": str(self.invocation_id),
74
  "target": "chat",
75
  "type": 4,
76
  }
77
+ self.invocation_id += 1
78
 
79
 
80
  class Conversation:
 
89
  "conversationSignature": None,
90
  "result": {"value": "Success", "message": None},
91
  }
 
 
 
92
  # Build request
93
  headers = {
94
  "accept": "application/json",
 
112
  "x-ms-useragent": "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Linuxx86_64",
113
  }
114
  # Create cookies
115
+ cookies = {
116
+ "_U": os.environ.get("BING_U")
117
+ }
118
  # Send GET request
119
  response = requests.get(
120
  "https://www.bing.com/turing/conversation/create",
 
122
  cookies=cookies,
123
  timeout=30,
124
  )
125
+ if response.status_code != 200:
126
+ raise Exception("Authentication failed")
127
  # Return response
128
  self.struct = response.json()
129
 
 
130
  class ChatHub:
131
  """
132
  Chat API
133
  """
134
 
135
  def __init__(self) -> None:
136
+ self.wss: websockets.WebSocketClientProtocol
137
+ self.request: ChatHubRequest
138
+ self.loop: bool
139
+
140
+ async def init(self, conversation: Conversation) -> None:
141
+ """
142
+ Separate initialization to allow async
143
+ """
144
+ self.wss = await websockets.connect("wss://sydney.bing.com/sydney/ChatHub")
145
+ self.request = ChatHubRequest(
146
+ conversation_signature=conversation.struct["conversationSignature"],
147
+ client_id=conversation.struct["clientId"],
148
+ conversation_id=conversation.struct["conversationId"],
149
+ )
150
+ self.loop = True
151
+ await self.__initial_handshake()
152
+
153
+ # Make async ping loop (long running)
154
+ self.task = asyncio.create_task(self.__ping())
155
+
156
+
157
+ async def ask(self, prompt: str) -> str:
158
+ """
159
+ Ask a question to the bot
160
+ """
161
+ # Construct a ChatHub request
162
+ self.request.update(prompt=prompt)
163
+ # Send request
164
+ await self.wss.send(append_identifier(self.request.struct))
165
  while True:
166
+ objects = str(await self.wss.recv()).split("")
167
+ for obj in objects:
168
+ if obj is None or obj == "":
169
+ continue
170
+ response = json.loads(obj)
171
+ if response.get("type") == 2:
172
+ return response
173
+
174
+ async def __initial_handshake(self):
175
+ await self.wss.send(append_identifier({"protocol": "json", "version": 1}))
176
+ await self.wss.send(append_identifier({"type": 6}))
177
+
178
+ async def __ping(self):
179
+ while self.loop:
180
+ try:
181
+ await asyncio.sleep(5)
182
+ except asyncio.CancelledError:
183
  break
184
+ await self.wss.send(append_identifier({"type": 6}))
185
+
186
+ async def close(self):
187
  """
188
+ Close the connection
189
  """
190
+ self.loop = False
191
+ await self.wss.close()
192
+ self.task.cancel()
193
 
194
 
195
+ class Chatbot:
196
  """
197
+ Combines everything to make it seamless
198
  """
199
+ def __init__(self) -> None:
200
+ self.conversation: Conversation
201
+ self.chat_hub: ChatHub
202
+ async def a_start(self) -> None:
203
+ """
204
+ Separate initialization to allow async
205
+ """
206
+ self.conversation = Conversation()
207
+ self.chat_hub = ChatHub()
208
+ await self.chat_hub.init(conversation=self.conversation)
209
 
210
+ async def a_ask(self, prompt: str) -> str:
211
+ """
212
+ Ask a question to the bot
213
+ """
214
+ return await self.chat_hub.ask(prompt=prompt)
215
+ async def a_close(self):
216
+ """
217
+ Close the connection
218
+ """
219
+ await self.chat_hub.close()
220
 
 
 
221
 
222
+ async def main():
223
+ print("Initializing...")
224
+ bot = Chatbot()
225
+ await bot.a_start()
226
+ while True:
227
+ prompt = input("You: ")
228
+ if prompt == "!exit":
229
+ break
230
+ print("Bot:", (await bot.a_ask(prompt=prompt))["item"]["messages"][1]["text"])
231
+ await bot.a_close()
232
+ if __name__ == "__main__":
233
  asyncio.run(main())
templates/chathub_request.json DELETED
@@ -1,55 +0,0 @@
1
- {
2
- "arguments": [
3
- {
4
- "source": "cib",
5
- "optionsSets": [
6
- "nlu_direct_response_filter",
7
- "deepleo",
8
- "enable_debug_commands",
9
- "disable_emoji_spoken_text",
10
- "responsible_ai_policy_235",
11
- "enablemm"
12
- ],
13
- "allowedMessageTypes": [
14
- "Chat",
15
- "InternalSearchQuery",
16
- "InternalSearchResult",
17
- "InternalLoaderMessage",
18
- "RenderCardRequest",
19
- "AdsQuery",
20
- "SemanticSerp"
21
- ],
22
- "sliceIds": [],
23
- "traceId": "63e48421455345f0854475fe03c0c78a",
24
- "isStartOfSession": true,
25
- "message": {
26
- "locale": "en-US",
27
- "market": "en-US",
28
- "region": "SG",
29
- "location": "lat:0.000000;long:0.000000;re=0m;",
30
- "locationHints": [
31
- {
32
- "country": "Singapore",
33
- "timezoneoffset": 8,
34
- "countryConfidence": 8,
35
- "Center": { "Latitude": 0, "Longitude": 0 },
36
- "RegionType": 2,
37
- "SourceType": 1
38
- }
39
- ],
40
- "timestamp": "2023-02-09T13:26:58+08:00",
41
- "author": "user",
42
- "inputMethod": "Keyboard",
43
- "text": "Say this is a test",
44
- "messageType": "Chat"
45
- },
46
- "conversationSignature": "<|CONVERSATION_SIGNATURE|>",
47
- "participant": { "id": "<|CLIENT_ID|>" },
48
- "conversationId": "<|CONVERSATION_ID|>",
49
- "previousMessages": []
50
- }
51
- ],
52
- "invocationId": "1",
53
- "target": "chat",
54
- "type": 4
55
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
templates/chathub_request_backup.json DELETED
@@ -1,86 +0,0 @@
1
- {
2
- "arguments": [
3
- {
4
- "source": "cib",
5
- "optionsSets": [
6
- "nlu_direct_response_filter",
7
- "deepleo",
8
- "enable_debug_commands",
9
- "disable_emoji_spoken_text",
10
- "responsible_ai_policy_235",
11
- "enablemm"
12
- ],
13
- "allowedMessageTypes": [
14
- "Chat",
15
- "InternalSearchQuery",
16
- "InternalSearchResult",
17
- "InternalLoaderMessage",
18
- "RenderCardRequest",
19
- "AdsQuery",
20
- "SemanticSerp"
21
- ],
22
- "sliceIds": [],
23
- "traceId": "63e48421455345f0854475fe03c0c78a",
24
- "isStartOfSession": true,
25
- "message": {
26
- "locale": "en-US",
27
- "market": "en-US",
28
- "region": "SG",
29
- "location": "lat:0.000000;long:0.000000;re=0m;",
30
- "locationHints": [
31
- {
32
- "country": "Singapore",
33
- "timezoneoffset": 8,
34
- "countryConfidence": 8,
35
- "Center": { "Latitude": 0, "Longitude": 0 },
36
- "RegionType": 2,
37
- "SourceType": 1
38
- }
39
- ],
40
- "timestamp": "2023-02-09T13:26:58+08:00",
41
- "author": "user",
42
- "inputMethod": "Keyboard",
43
- "text": "Say this is a test",
44
- "messageType": "Chat"
45
- },
46
- "conversationSignature": "<|CONVERSATION_SIGNATURE|>",
47
- "participant": { "id": "<|CLIENT_ID|>" },
48
- "conversationId": "<|CONVERSATION_ID|>",
49
- "previousMessages": [
50
- {
51
- "text": "Okay, I’ve cleared the slate for a fresh start. What can I help you explore now?",
52
- "author": "bot",
53
- "adaptiveCards": [],
54
- "suggestedResponses": [
55
- {
56
- "text": "Teach me a new word",
57
- "contentOrigin": "DeepLeo",
58
- "messageType": "Suggestion",
59
- "messageId": "0b483c19-409a-746c-9c44-2779234c04e4",
60
- "offense": "Unknown"
61
- },
62
- {
63
- "text": "Why do humans need sleep?",
64
- "contentOrigin": "DeepLeo",
65
- "messageType": "Suggestion",
66
- "messageId": "b9e18704-b29d-25de-951d-c13aa1b0252c",
67
- "offense": "Unknown"
68
- },
69
- {
70
- "text": "I want to learn a new skill",
71
- "contentOrigin": "DeepLeo",
72
- "messageType": "Suggestion",
73
- "messageId": "9092c1e7-4ddf-9726-3da6-efadaa8bc9cb",
74
- "offense": "Unknown"
75
- }
76
- ],
77
- "messageId": "57cda79f-4afa-3723-1bad-394e61f1e590",
78
- "messageType": "Chat"
79
- }
80
- ]
81
- }
82
- ],
83
- "invocationId": "2",
84
- "target": "chat",
85
- "type": 4
86
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
templates/cookies.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "_U": "1YEL2O07jUf0Rdw3Li02tXbvn47K5pNQcjqdjILEq-9hgsxvyYD9bMjIGxICr3nmVHIcWKgZLVGUVxhdQDHY-WWd8spn_8yNwT-pweGVb6115nmreE8zOa44HLPcHqzvaSOuVVWfip7itwiUOakv6_3SxK2k2YVb9fA-d88MAINsknY9mnaA3-fSXdMea5-K-"
3
- }