webscout 1.1.5__py3-none-any.whl → 1.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of webscout might be problematic. Click here for more details.
- webscout/AI.py +938 -40
- webscout/AIbase.py +70 -0
- webscout/AIutel.py +655 -0
- webscout/HelpingAI.py +192 -192
- webscout/LLM.py +67 -67
- webscout/utils.py +52 -11
- webscout/version.py +1 -1
- {webscout-1.1.5.dist-info → webscout-1.1.7.dist-info}/METADATA +92 -17
- webscout-1.1.7.dist-info/RECORD +20 -0
- webscout-1.1.5.dist-info/RECORD +0 -18
- {webscout-1.1.5.dist-info → webscout-1.1.7.dist-info}/LICENSE.md +0 -0
- {webscout-1.1.5.dist-info → webscout-1.1.7.dist-info}/WHEEL +0 -0
- {webscout-1.1.5.dist-info → webscout-1.1.7.dist-info}/entry_points.txt +0 -0
- {webscout-1.1.5.dist-info → webscout-1.1.7.dist-info}/top_level.txt +0 -0
webscout/HelpingAI.py
CHANGED
|
@@ -1,192 +1,192 @@
|
|
|
1
|
-
import warnings
|
|
2
|
-
from selenium import webdriver
|
|
3
|
-
from selenium.webdriver.chrome.options import Options
|
|
4
|
-
from selenium.webdriver.common.by import By
|
|
5
|
-
from selenium.common.exceptions import NoSuchElementException
|
|
6
|
-
import time
|
|
7
|
-
import os
|
|
8
|
-
import requests
|
|
9
|
-
from rich import print
|
|
10
|
-
from dotenv import load_dotenv
|
|
11
|
-
import random
|
|
12
|
-
import string
|
|
13
|
-
import json
|
|
14
|
-
from typing import NoReturn, List, Dict, Union
|
|
15
|
-
import requests
|
|
16
|
-
from uuid import uuid4
|
|
17
|
-
from re import findall
|
|
18
|
-
from curl_cffi.requests import get, RequestsError
|
|
19
|
-
import time
|
|
20
|
-
from selenium import webdriver
|
|
21
|
-
from selenium.webdriver.chrome.options import Options
|
|
22
|
-
from selenium.webdriver.common.by import By
|
|
23
|
-
from selenium.webdriver.support import expected_conditions as EC
|
|
24
|
-
from selenium.webdriver.support.ui import WebDriverWait
|
|
25
|
-
from halo import Halo
|
|
26
|
-
|
|
27
|
-
class ChatBot:
|
|
28
|
-
def __init__(self):
|
|
29
|
-
load_dotenv()
|
|
30
|
-
options = Options()
|
|
31
|
-
options.add_argument('--no-sandbox')
|
|
32
|
-
options.add_argument('--headless')
|
|
33
|
-
options.add_argument('--disable-dev-shm-usage')
|
|
34
|
-
options.add_argument("start-maximized")
|
|
35
|
-
options.add_argument("disable-infobars")
|
|
36
|
-
options.add_argument("--disable-extensions")
|
|
37
|
-
options.add_argument("--disable-gpu")
|
|
38
|
-
options.add_argument("--disable-dev-shm-usage")
|
|
39
|
-
options.add_argument('--log-level=3') # Add this line
|
|
40
|
-
warnings.simplefilter("ignore")
|
|
41
|
-
# Initialize WebDriver
|
|
42
|
-
self.driver = webdriver.Chrome(options=options)
|
|
43
|
-
|
|
44
|
-
self.HelpingAI = "https://vortex.zapier.app/"
|
|
45
|
-
# Navigate to the target URL
|
|
46
|
-
self.driver.get(self.HelpingAI)
|
|
47
|
-
time.sleep(7)
|
|
48
|
-
|
|
49
|
-
# Security Bypass: Refresh the page if the title contains 'just a moment'
|
|
50
|
-
while 'just a moment' in self.driver.title.lower():
|
|
51
|
-
self.driver.refresh()
|
|
52
|
-
|
|
53
|
-
# Initialize Chat_Num
|
|
54
|
-
self.Chat_Num = 2
|
|
55
|
-
|
|
56
|
-
# Function to increment Chat_Num
|
|
57
|
-
def increment_chat_num(self):
|
|
58
|
-
self.Chat_Num = str(int(self.Chat_Num) + 1)
|
|
59
|
-
|
|
60
|
-
# Function to send a query and retrieve response
|
|
61
|
-
def send_query(self, query):
|
|
62
|
-
text_box_xpath = "/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/form/fieldset/textarea"
|
|
63
|
-
send_button_xpath = "/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/form/fieldset/button"
|
|
64
|
-
response_xpath = f"/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/div/div/div[{self.Chat_Num}]/div[2]"
|
|
65
|
-
button_xpath = f"/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/div/div/div[{self.Chat_Num}]/div[1]/div/form/div/div[1]/button"
|
|
66
|
-
|
|
67
|
-
# Find the text box, enter query, and click send
|
|
68
|
-
text_box = self.driver.find_element(by=By.XPATH, value=text_box_xpath)
|
|
69
|
-
text_box.clear()
|
|
70
|
-
text_box.send_keys(query)
|
|
71
|
-
time.sleep(0.25) # Pause for 1 second after typing query
|
|
72
|
-
|
|
73
|
-
send_button = self.driver.find_element(by=By.XPATH, value=send_button_xpath)
|
|
74
|
-
send_button.click()
|
|
75
|
-
|
|
76
|
-
# Continuously check for the presence of the button every second
|
|
77
|
-
while True:
|
|
78
|
-
try:
|
|
79
|
-
button = self.driver.find_element(by=By.XPATH, value=button_xpath)
|
|
80
|
-
# If the button is found, retrieve and print the response
|
|
81
|
-
response = self.driver.find_element(by=By.XPATH, value=response_xpath).text
|
|
82
|
-
print("🤖:", response)
|
|
83
|
-
break
|
|
84
|
-
except NoSuchElementException:
|
|
85
|
-
time.sleep(0.25) # If the button is not found, wait for 1 second before checking again
|
|
86
|
-
|
|
87
|
-
self.increment_chat_num()
|
|
88
|
-
|
|
89
|
-
# Function to ask the user for a query, send it, and print the response
|
|
90
|
-
def query_chat(self):
|
|
91
|
-
while True:
|
|
92
|
-
query = input("🧑: ")
|
|
93
|
-
if query.lower() == 'exit':
|
|
94
|
-
break
|
|
95
|
-
|
|
96
|
-
self.send_query(query)
|
|
97
|
-
time.sleep(0.25) # Pause for 1 second before asking for the next query
|
|
98
|
-
|
|
99
|
-
# Close the browser window
|
|
100
|
-
def close(self):
|
|
101
|
-
self.driver.quit()
|
|
102
|
-
|
|
103
|
-
class WEBS:
|
|
104
|
-
def __init__(self):
|
|
105
|
-
load_dotenv()
|
|
106
|
-
options = Options()
|
|
107
|
-
options.add_argument('--no-sandbox')
|
|
108
|
-
options.add_argument('--headless')
|
|
109
|
-
options.add_argument('--disable-dev-shm-usage')
|
|
110
|
-
options.add_argument("start-maximized")
|
|
111
|
-
options.add_argument("disable-infobars")
|
|
112
|
-
options.add_argument("--disable-extensions")
|
|
113
|
-
options.add_argument("--disable-gpu")
|
|
114
|
-
options.add_argument("--disable-dev-shm-usage")
|
|
115
|
-
options.add_argument('--log-level=3')
|
|
116
|
-
warnings.simplefilter("ignore")
|
|
117
|
-
# Initialize WebDriver without specifying the path to the driver
|
|
118
|
-
self.driver = webdriver.Chrome(options=options)
|
|
119
|
-
|
|
120
|
-
self.HelpingAI = "https://vortex.zapier.app/"
|
|
121
|
-
# Navigate to the target URL
|
|
122
|
-
self.driver.get(self.HelpingAI)
|
|
123
|
-
time.sleep(7)
|
|
124
|
-
|
|
125
|
-
# Security Bypass: Refresh the page if the title contains 'just a moment'
|
|
126
|
-
while 'just a moment' in self.driver.title.lower():
|
|
127
|
-
self.driver.refresh()
|
|
128
|
-
|
|
129
|
-
# Initialize Chat_Num
|
|
130
|
-
self.Chat_Num = 2
|
|
131
|
-
|
|
132
|
-
# Function to increment Chat_Num
|
|
133
|
-
def increment_chat_num(self):
|
|
134
|
-
self.Chat_Num = str(int(self.Chat_Num) + 1)
|
|
135
|
-
|
|
136
|
-
# Function to send a query and retrieve response
|
|
137
|
-
def send_query(self, prompt):
|
|
138
|
-
text_box_xpath = "/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/form/fieldset/textarea"
|
|
139
|
-
send_button_xpath = "/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/form/fieldset/button"
|
|
140
|
-
response_xpath = f"/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/div/div/div[{self.Chat_Num}]/div[2]"
|
|
141
|
-
button_xpath = f"/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/div/div/div[{self.Chat_Num}]/div[1]/div/form/div/div[1]/button"
|
|
142
|
-
|
|
143
|
-
# Find the text box, enter prompt, and click send
|
|
144
|
-
text_box = self.driver.find_element(by=By.XPATH, value=text_box_xpath)
|
|
145
|
-
text_box.clear()
|
|
146
|
-
text_box.send_keys(prompt)
|
|
147
|
-
time.sleep(1) # Pause for 1 second after typing prompt
|
|
148
|
-
|
|
149
|
-
send_button = self.driver.find_element(by=By.XPATH, value=send_button_xpath)
|
|
150
|
-
send_button.click()
|
|
151
|
-
|
|
152
|
-
# Continuously check for the presence of the button every second
|
|
153
|
-
while True:
|
|
154
|
-
try:
|
|
155
|
-
button = self.driver.find_element(by=By.XPATH, value=button_xpath)
|
|
156
|
-
# If the button is found, retrieve and print the response
|
|
157
|
-
response = self.driver.find_element(by=By.XPATH, value=response_xpath).text
|
|
158
|
-
print("🤖:", response)
|
|
159
|
-
break
|
|
160
|
-
except NoSuchElementException:
|
|
161
|
-
time.sleep(0.25) # If the button is not found, wait for 1 second before checking again
|
|
162
|
-
|
|
163
|
-
self.increment_chat_num()
|
|
164
|
-
|
|
165
|
-
# Function to perform web search
|
|
166
|
-
def web_search(self, query):
|
|
167
|
-
url = "https://abhaykoul-webscout1.hf.space/mws"
|
|
168
|
-
payload = {"query": query}
|
|
169
|
-
response = requests.post(url, json=payload)
|
|
170
|
-
|
|
171
|
-
if response.status_code == 200:
|
|
172
|
-
return response.json()
|
|
173
|
-
else:
|
|
174
|
-
print("Error:", response.status_code)
|
|
175
|
-
|
|
176
|
-
# Function to ask the user for a prompt, send it, and print the response
|
|
177
|
-
def query_chat(self):
|
|
178
|
-
while True:
|
|
179
|
-
prompt = input("🧑: ")
|
|
180
|
-
if prompt.lower() == 'exit':
|
|
181
|
-
break
|
|
182
|
-
|
|
183
|
-
# Perform web search
|
|
184
|
-
search_results = self.web_search(prompt)
|
|
185
|
-
|
|
186
|
-
# Pass the search results and the prompt to the AI
|
|
187
|
-
self.send_query(f"users question:{prompt} web search results: {search_results} Answer in HelpingAI style**note you have internet access and only use search_results when necessary also dont give links or urls (when users is asking something that needs realtime data)**")
|
|
188
|
-
time.sleep(0.25) # Pause for 1 second before asking for the next prompt
|
|
189
|
-
|
|
190
|
-
# Close the browser window
|
|
191
|
-
def close(self):
|
|
192
|
-
self.driver.quit()
|
|
1
|
+
import warnings
|
|
2
|
+
from selenium import webdriver
|
|
3
|
+
from selenium.webdriver.chrome.options import Options
|
|
4
|
+
from selenium.webdriver.common.by import By
|
|
5
|
+
from selenium.common.exceptions import NoSuchElementException
|
|
6
|
+
import time
|
|
7
|
+
import os
|
|
8
|
+
import requests
|
|
9
|
+
from rich import print
|
|
10
|
+
from dotenv import load_dotenv
|
|
11
|
+
import random
|
|
12
|
+
import string
|
|
13
|
+
import json
|
|
14
|
+
from typing import NoReturn, List, Dict, Union
|
|
15
|
+
import requests
|
|
16
|
+
from uuid import uuid4
|
|
17
|
+
from re import findall
|
|
18
|
+
from curl_cffi.requests import get, RequestsError
|
|
19
|
+
import time
|
|
20
|
+
from selenium import webdriver
|
|
21
|
+
from selenium.webdriver.chrome.options import Options
|
|
22
|
+
from selenium.webdriver.common.by import By
|
|
23
|
+
from selenium.webdriver.support import expected_conditions as EC
|
|
24
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
|
25
|
+
from halo import Halo
|
|
26
|
+
|
|
27
|
+
class ChatBot:
|
|
28
|
+
def __init__(self):
|
|
29
|
+
load_dotenv()
|
|
30
|
+
options = Options()
|
|
31
|
+
options.add_argument('--no-sandbox')
|
|
32
|
+
options.add_argument('--headless')
|
|
33
|
+
options.add_argument('--disable-dev-shm-usage')
|
|
34
|
+
options.add_argument("start-maximized")
|
|
35
|
+
options.add_argument("disable-infobars")
|
|
36
|
+
options.add_argument("--disable-extensions")
|
|
37
|
+
options.add_argument("--disable-gpu")
|
|
38
|
+
options.add_argument("--disable-dev-shm-usage")
|
|
39
|
+
options.add_argument('--log-level=3') # Add this line
|
|
40
|
+
warnings.simplefilter("ignore")
|
|
41
|
+
# Initialize WebDriver
|
|
42
|
+
self.driver = webdriver.Chrome(options=options)
|
|
43
|
+
|
|
44
|
+
self.HelpingAI = "https://vortex.zapier.app/"
|
|
45
|
+
# Navigate to the target URL
|
|
46
|
+
self.driver.get(self.HelpingAI)
|
|
47
|
+
time.sleep(7)
|
|
48
|
+
|
|
49
|
+
# Security Bypass: Refresh the page if the title contains 'just a moment'
|
|
50
|
+
while 'just a moment' in self.driver.title.lower():
|
|
51
|
+
self.driver.refresh()
|
|
52
|
+
|
|
53
|
+
# Initialize Chat_Num
|
|
54
|
+
self.Chat_Num = 2
|
|
55
|
+
|
|
56
|
+
# Function to increment Chat_Num
|
|
57
|
+
def increment_chat_num(self):
|
|
58
|
+
self.Chat_Num = str(int(self.Chat_Num) + 1)
|
|
59
|
+
|
|
60
|
+
# Function to send a query and retrieve response
|
|
61
|
+
def send_query(self, query):
|
|
62
|
+
text_box_xpath = "/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/form/fieldset/textarea"
|
|
63
|
+
send_button_xpath = "/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/form/fieldset/button"
|
|
64
|
+
response_xpath = f"/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/div/div/div[{self.Chat_Num}]/div[2]"
|
|
65
|
+
button_xpath = f"/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/div/div/div[{self.Chat_Num}]/div[1]/div/form/div/div[1]/button"
|
|
66
|
+
|
|
67
|
+
# Find the text box, enter query, and click send
|
|
68
|
+
text_box = self.driver.find_element(by=By.XPATH, value=text_box_xpath)
|
|
69
|
+
text_box.clear()
|
|
70
|
+
text_box.send_keys(query)
|
|
71
|
+
time.sleep(0.25) # Pause for 1 second after typing query
|
|
72
|
+
|
|
73
|
+
send_button = self.driver.find_element(by=By.XPATH, value=send_button_xpath)
|
|
74
|
+
send_button.click()
|
|
75
|
+
|
|
76
|
+
# Continuously check for the presence of the button every second
|
|
77
|
+
while True:
|
|
78
|
+
try:
|
|
79
|
+
button = self.driver.find_element(by=By.XPATH, value=button_xpath)
|
|
80
|
+
# If the button is found, retrieve and print the response
|
|
81
|
+
response = self.driver.find_element(by=By.XPATH, value=response_xpath).text
|
|
82
|
+
print("🤖:", response)
|
|
83
|
+
break
|
|
84
|
+
except NoSuchElementException:
|
|
85
|
+
time.sleep(0.25) # If the button is not found, wait for 1 second before checking again
|
|
86
|
+
|
|
87
|
+
self.increment_chat_num()
|
|
88
|
+
|
|
89
|
+
# Function to ask the user for a query, send it, and print the response
|
|
90
|
+
def query_chat(self):
|
|
91
|
+
while True:
|
|
92
|
+
query = input("🧑: ")
|
|
93
|
+
if query.lower() == 'exit':
|
|
94
|
+
break
|
|
95
|
+
|
|
96
|
+
self.send_query(query)
|
|
97
|
+
time.sleep(0.25) # Pause for 1 second before asking for the next query
|
|
98
|
+
|
|
99
|
+
# Close the browser window
|
|
100
|
+
def close(self):
|
|
101
|
+
self.driver.quit()
|
|
102
|
+
|
|
103
|
+
class WEBS:
|
|
104
|
+
def __init__(self):
|
|
105
|
+
load_dotenv()
|
|
106
|
+
options = Options()
|
|
107
|
+
options.add_argument('--no-sandbox')
|
|
108
|
+
options.add_argument('--headless')
|
|
109
|
+
options.add_argument('--disable-dev-shm-usage')
|
|
110
|
+
options.add_argument("start-maximized")
|
|
111
|
+
options.add_argument("disable-infobars")
|
|
112
|
+
options.add_argument("--disable-extensions")
|
|
113
|
+
options.add_argument("--disable-gpu")
|
|
114
|
+
options.add_argument("--disable-dev-shm-usage")
|
|
115
|
+
options.add_argument('--log-level=3')
|
|
116
|
+
warnings.simplefilter("ignore")
|
|
117
|
+
# Initialize WebDriver without specifying the path to the driver
|
|
118
|
+
self.driver = webdriver.Chrome(options=options)
|
|
119
|
+
|
|
120
|
+
self.HelpingAI = "https://vortex.zapier.app/"
|
|
121
|
+
# Navigate to the target URL
|
|
122
|
+
self.driver.get(self.HelpingAI)
|
|
123
|
+
time.sleep(7)
|
|
124
|
+
|
|
125
|
+
# Security Bypass: Refresh the page if the title contains 'just a moment'
|
|
126
|
+
while 'just a moment' in self.driver.title.lower():
|
|
127
|
+
self.driver.refresh()
|
|
128
|
+
|
|
129
|
+
# Initialize Chat_Num
|
|
130
|
+
self.Chat_Num = 2
|
|
131
|
+
|
|
132
|
+
# Function to increment Chat_Num
|
|
133
|
+
def increment_chat_num(self):
|
|
134
|
+
self.Chat_Num = str(int(self.Chat_Num) + 1)
|
|
135
|
+
|
|
136
|
+
# Function to send a query and retrieve response
|
|
137
|
+
def send_query(self, prompt):
|
|
138
|
+
text_box_xpath = "/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/form/fieldset/textarea"
|
|
139
|
+
send_button_xpath = "/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/form/fieldset/button"
|
|
140
|
+
response_xpath = f"/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/div/div/div[{self.Chat_Num}]/div[2]"
|
|
141
|
+
button_xpath = f"/html/body/div[1]/main/div[1]/div/div/div/div/div/div/div/div/div/div[{self.Chat_Num}]/div[1]/div/form/div/div[1]/button"
|
|
142
|
+
|
|
143
|
+
# Find the text box, enter prompt, and click send
|
|
144
|
+
text_box = self.driver.find_element(by=By.XPATH, value=text_box_xpath)
|
|
145
|
+
text_box.clear()
|
|
146
|
+
text_box.send_keys(prompt)
|
|
147
|
+
time.sleep(1) # Pause for 1 second after typing prompt
|
|
148
|
+
|
|
149
|
+
send_button = self.driver.find_element(by=By.XPATH, value=send_button_xpath)
|
|
150
|
+
send_button.click()
|
|
151
|
+
|
|
152
|
+
# Continuously check for the presence of the button every second
|
|
153
|
+
while True:
|
|
154
|
+
try:
|
|
155
|
+
button = self.driver.find_element(by=By.XPATH, value=button_xpath)
|
|
156
|
+
# If the button is found, retrieve and print the response
|
|
157
|
+
response = self.driver.find_element(by=By.XPATH, value=response_xpath).text
|
|
158
|
+
print("🤖:", response)
|
|
159
|
+
break
|
|
160
|
+
except NoSuchElementException:
|
|
161
|
+
time.sleep(0.25) # If the button is not found, wait for 1 second before checking again
|
|
162
|
+
|
|
163
|
+
self.increment_chat_num()
|
|
164
|
+
|
|
165
|
+
# Function to perform web search
|
|
166
|
+
def web_search(self, query):
|
|
167
|
+
url = "https://abhaykoul-webscout1.hf.space/mws"
|
|
168
|
+
payload = {"query": query}
|
|
169
|
+
response = requests.post(url, json=payload)
|
|
170
|
+
|
|
171
|
+
if response.status_code == 200:
|
|
172
|
+
return response.json()
|
|
173
|
+
else:
|
|
174
|
+
print("Error:", response.status_code)
|
|
175
|
+
|
|
176
|
+
# Function to ask the user for a prompt, send it, and print the response
|
|
177
|
+
def query_chat(self):
|
|
178
|
+
while True:
|
|
179
|
+
prompt = input("🧑: ")
|
|
180
|
+
if prompt.lower() == 'exit':
|
|
181
|
+
break
|
|
182
|
+
|
|
183
|
+
# Perform web search
|
|
184
|
+
search_results = self.web_search(prompt)
|
|
185
|
+
|
|
186
|
+
# Pass the search results and the prompt to the AI
|
|
187
|
+
self.send_query(f"users question:{prompt} web search results: {search_results} Answer in HelpingAI style**note you have internet access and only use search_results when necessary also dont give links or urls (when users is asking something that needs realtime data)**")
|
|
188
|
+
time.sleep(0.25) # Pause for 1 second before asking for the next prompt
|
|
189
|
+
|
|
190
|
+
# Close the browser window
|
|
191
|
+
def close(self):
|
|
192
|
+
self.driver.quit()
|
webscout/LLM.py
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import argparse
|
|
2
|
-
import requests
|
|
3
|
-
import json
|
|
4
|
-
from typing import List, Dict, Union
|
|
5
|
-
|
|
6
|
-
class LLM:
|
|
7
|
-
def __init__(self, model: str, system_message: str = "You are a Helpful AI."):
|
|
8
|
-
self.model = model
|
|
9
|
-
self.conversation_history = [{"role": "system", "content": system_message}]
|
|
10
|
-
|
|
11
|
-
def mistral_chat(self, messages: List[Dict[str, str]]) -> Union[str, None]:
|
|
12
|
-
url = "https://api.deepinfra.com/v1/openai/chat/completions"
|
|
13
|
-
headers = {
|
|
14
|
-
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
|
|
15
|
-
'Accept-Language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
|
|
16
|
-
'Cache-Control': 'no-cache',
|
|
17
|
-
'Connection': 'keep-alive',
|
|
18
|
-
'Content-Type': 'application/json',
|
|
19
|
-
'Origin': 'https://deepinfra.com',
|
|
20
|
-
'Pragma': 'no-cache',
|
|
21
|
-
'Referer': 'https://deepinfra.com/',
|
|
22
|
-
'Sec-Fetch-Dest': 'empty',
|
|
23
|
-
'Sec-Fetch-Mode': 'cors',
|
|
24
|
-
'Sec-Fetch-Site': 'same-site',
|
|
25
|
-
'X-Deepinfra-Source': 'web-embed',
|
|
26
|
-
'accept': 'text/event-stream',
|
|
27
|
-
'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
|
|
28
|
-
'sec-ch-ua-mobile': '?0',
|
|
29
|
-
'sec-ch-ua-platform': '"macOS"'
|
|
30
|
-
}
|
|
31
|
-
data = json.dumps(
|
|
32
|
-
{
|
|
33
|
-
'model': self.model,
|
|
34
|
-
'messages': messages,
|
|
35
|
-
'temperature': 0.7,
|
|
36
|
-
'max_tokens': 8028,
|
|
37
|
-
'stop': [],
|
|
38
|
-
'stream': False #dont change it
|
|
39
|
-
}, separators=(',', ':')
|
|
40
|
-
)
|
|
41
|
-
try:
|
|
42
|
-
result = requests.post(url=url, data=data, headers=headers)
|
|
43
|
-
return result.json()['choices'][0]['message']['content']
|
|
44
|
-
except:
|
|
45
|
-
return None
|
|
46
|
-
|
|
47
|
-
def chat(self):
|
|
48
|
-
while True:
|
|
49
|
-
prompt = input("👦: ")
|
|
50
|
-
user_message = {"role": "user", "content": prompt}
|
|
51
|
-
self.conversation_history.append(user_message)
|
|
52
|
-
try:
|
|
53
|
-
resp = self.mistral_chat(self.conversation_history)
|
|
54
|
-
print(f"🤖: {resp}")
|
|
55
|
-
self.conversation_history.append({"role": "assistant", "content": resp})
|
|
56
|
-
except Exception as e:
|
|
57
|
-
print(f"🤖: Oops, something went wrong: {e}! Looks like even AI needs some oiling sometimes.")
|
|
58
|
-
|
|
59
|
-
if __name__ == "__main__":
|
|
60
|
-
parser = argparse.ArgumentParser(description='LLM CLI', epilog='To use a specific model, run:\n'
|
|
61
|
-
'python -m webscout.LLM model_name\n'
|
|
62
|
-
'Replace "model_name" with the name of the model you wish to use It supports ALL text generation models on deepinfra.com.')
|
|
63
|
-
parser.add_argument('model', type=str, help='Model to use for text generation. Specify the full model name, e.g., "mistralai/Mistral-7B-Instruct-v0.1".')
|
|
64
|
-
parser.add_argument('--system-message', type=str, default="You are a Helpful AI.", help='Custom system prompt for the AI.')
|
|
65
|
-
args = parser.parse_args()
|
|
66
|
-
|
|
67
|
-
LLM = LLM(args.model, args.system_message)
|
|
1
|
+
import argparse
|
|
2
|
+
import requests
|
|
3
|
+
import json
|
|
4
|
+
from typing import List, Dict, Union
|
|
5
|
+
|
|
6
|
+
class LLM:
|
|
7
|
+
def __init__(self, model: str, system_message: str = "You are a Helpful AI."):
|
|
8
|
+
self.model = model
|
|
9
|
+
self.conversation_history = [{"role": "system", "content": system_message}]
|
|
10
|
+
|
|
11
|
+
def mistral_chat(self, messages: List[Dict[str, str]]) -> Union[str, None]:
|
|
12
|
+
url = "https://api.deepinfra.com/v1/openai/chat/completions"
|
|
13
|
+
headers = {
|
|
14
|
+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
|
|
15
|
+
'Accept-Language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
|
|
16
|
+
'Cache-Control': 'no-cache',
|
|
17
|
+
'Connection': 'keep-alive',
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
'Origin': 'https://deepinfra.com',
|
|
20
|
+
'Pragma': 'no-cache',
|
|
21
|
+
'Referer': 'https://deepinfra.com/',
|
|
22
|
+
'Sec-Fetch-Dest': 'empty',
|
|
23
|
+
'Sec-Fetch-Mode': 'cors',
|
|
24
|
+
'Sec-Fetch-Site': 'same-site',
|
|
25
|
+
'X-Deepinfra-Source': 'web-embed',
|
|
26
|
+
'accept': 'text/event-stream',
|
|
27
|
+
'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
|
|
28
|
+
'sec-ch-ua-mobile': '?0',
|
|
29
|
+
'sec-ch-ua-platform': '"macOS"'
|
|
30
|
+
}
|
|
31
|
+
data = json.dumps(
|
|
32
|
+
{
|
|
33
|
+
'model': self.model,
|
|
34
|
+
'messages': messages,
|
|
35
|
+
'temperature': 0.7,
|
|
36
|
+
'max_tokens': 8028,
|
|
37
|
+
'stop': [],
|
|
38
|
+
'stream': False #dont change it
|
|
39
|
+
}, separators=(',', ':')
|
|
40
|
+
)
|
|
41
|
+
try:
|
|
42
|
+
result = requests.post(url=url, data=data, headers=headers)
|
|
43
|
+
return result.json()['choices'][0]['message']['content']
|
|
44
|
+
except:
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
def chat(self):
|
|
48
|
+
while True:
|
|
49
|
+
prompt = input("👦: ")
|
|
50
|
+
user_message = {"role": "user", "content": prompt}
|
|
51
|
+
self.conversation_history.append(user_message)
|
|
52
|
+
try:
|
|
53
|
+
resp = self.mistral_chat(self.conversation_history)
|
|
54
|
+
print(f"🤖: {resp}")
|
|
55
|
+
self.conversation_history.append({"role": "assistant", "content": resp})
|
|
56
|
+
except Exception as e:
|
|
57
|
+
print(f"🤖: Oops, something went wrong: {e}! Looks like even AI needs some oiling sometimes.")
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
parser = argparse.ArgumentParser(description='LLM CLI', epilog='To use a specific model, run:\n'
|
|
61
|
+
'python -m webscout.LLM model_name\n'
|
|
62
|
+
'Replace "model_name" with the name of the model you wish to use It supports ALL text generation models on deepinfra.com.')
|
|
63
|
+
parser.add_argument('model', type=str, help='Model to use for text generation. Specify the full model name, e.g., "mistralai/Mistral-7B-Instruct-v0.1".')
|
|
64
|
+
parser.add_argument('--system-message', type=str, default="You are a Helpful AI.", help='Custom system prompt for the AI.')
|
|
65
|
+
args = parser.parse_args()
|
|
66
|
+
|
|
67
|
+
LLM = LLM(args.model, args.system_message)
|
|
68
68
|
LLM.chat()
|
webscout/utils.py
CHANGED
|
@@ -1,38 +1,69 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import re
|
|
3
|
+
from decimal import Decimal
|
|
4
|
+
from functools import lru_cache
|
|
3
5
|
from html import unescape
|
|
4
|
-
from
|
|
6
|
+
from math import atan2, cos, radians, sin, sqrt
|
|
7
|
+
from typing import Any, Dict, List, Union
|
|
5
8
|
from urllib.parse import unquote
|
|
6
9
|
|
|
7
10
|
from .exceptions import WebscoutE
|
|
8
11
|
|
|
12
|
+
try:
|
|
13
|
+
import orjson
|
|
14
|
+
except ModuleNotFoundError:
|
|
15
|
+
HAS_ORJSON = False
|
|
16
|
+
else:
|
|
17
|
+
HAS_ORJSON = True
|
|
18
|
+
|
|
9
19
|
REGEX_500_IN_URL = re.compile(r"(?:\d{3}-\d{2}\.js)")
|
|
10
20
|
REGEX_STRIP_TAGS = re.compile("<.*?>")
|
|
11
|
-
REGEX_VQD = re.compile(rb"""vqd=['"]?([^&"']+)""")
|
|
12
21
|
|
|
13
22
|
|
|
14
|
-
def
|
|
15
|
-
|
|
23
|
+
def json_dumps(obj: Any) -> str:
|
|
24
|
+
try:
|
|
25
|
+
return orjson.dumps(obj).decode("utf-8") if HAS_ORJSON else json.dumps(obj)
|
|
26
|
+
except Exception as ex:
|
|
27
|
+
raise WebscoutE(f"{type(ex).__name__}: {ex}") from ex
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def json_loads(obj: Union[str, bytes]) -> Any:
|
|
16
31
|
try:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
32
|
+
return orjson.loads(obj) if HAS_ORJSON else json.loads(obj)
|
|
33
|
+
except Exception as ex:
|
|
34
|
+
raise WebscoutE(f"{type(ex).__name__}: {ex}") from ex
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _extract_vqd(html_bytes: bytes, keywords: str) -> str:
|
|
38
|
+
"""Extract vqd from html bytes."""
|
|
39
|
+
for c1, c1_len, c2 in (
|
|
40
|
+
(b'vqd="', 5, b'"'),
|
|
41
|
+
(b"vqd=", 4, b"&"),
|
|
42
|
+
(b"vqd='", 5, b"'"),
|
|
43
|
+
):
|
|
44
|
+
try:
|
|
45
|
+
start = html_bytes.index(c1) + c1_len
|
|
46
|
+
end = html_bytes.index(c2, start)
|
|
47
|
+
return html_bytes[start:end].decode()
|
|
48
|
+
except ValueError:
|
|
49
|
+
pass
|
|
22
50
|
raise WebscoutE(f"_extract_vqd() {keywords=} Could not extract vqd.")
|
|
23
51
|
|
|
24
52
|
|
|
25
|
-
def _text_extract_json(html_bytes: bytes, keywords: str) ->
|
|
53
|
+
def _text_extract_json(html_bytes: bytes, keywords: str) -> List[Dict[str, str]]:
|
|
26
54
|
"""text(backend="api") -> extract json from html."""
|
|
27
55
|
try:
|
|
28
56
|
start = html_bytes.index(b"DDG.pageLayout.load('d',") + 24
|
|
29
57
|
end = html_bytes.index(b");DDG.duckbar.load(", start)
|
|
30
58
|
data = html_bytes[start:end]
|
|
31
|
-
|
|
59
|
+
result: List[Dict[str, str]] = json_loads(data)
|
|
60
|
+
return result
|
|
32
61
|
except Exception as ex:
|
|
33
62
|
raise WebscoutE(f"_text_extract_json() {keywords=} {type(ex).__name__}: {ex}") from ex
|
|
63
|
+
raise WebscoutE(f"_text_extract_json() {keywords=} return None")
|
|
34
64
|
|
|
35
65
|
|
|
66
|
+
@lru_cache
|
|
36
67
|
def _is_500_in_url(url: str) -> bool:
|
|
37
68
|
"""Something like '506-00.js' inside the url."""
|
|
38
69
|
return bool(REGEX_500_IN_URL.search(url))
|
|
@@ -46,3 +77,13 @@ def _normalize(raw_html: str) -> str:
|
|
|
46
77
|
def _normalize_url(url: str) -> str:
|
|
47
78
|
"""Unquote URL and replace spaces with '+'."""
|
|
48
79
|
return unquote(url.replace(" ", "+")) if url else ""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _calculate_distance(lat1: Decimal, lon1: Decimal, lat2: Decimal, lon2: Decimal) -> float:
|
|
83
|
+
"""Calculate distance between two points in km. Haversine formula."""
|
|
84
|
+
R = 6371.0087714 # Earth's radius in km
|
|
85
|
+
rlat1, rlon1, rlat2, rlon2 = map(radians, [float(lat1), float(lon1), float(lat2), float(lon2)])
|
|
86
|
+
dlon, dlat = rlon2 - rlon1, rlat2 - rlat1
|
|
87
|
+
a = sin(dlat / 2) ** 2 + cos(rlat1) * cos(rlat2) * sin(dlon / 2) ** 2
|
|
88
|
+
c = 2 * atan2(sqrt(a), sqrt(1 - a))
|
|
89
|
+
return R * c
|
webscout/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "1.1.
|
|
1
|
+
__version__ = "1.1.7"
|
|
2
2
|
|