webscout 4.8__tar.gz → 5.0__tar.gz
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-4.8/webscout.egg-info → webscout-5.0}/PKG-INFO +25 -74
- {webscout-4.8 → webscout-5.0}/README.md +22 -73
- {webscout-4.8 → webscout-5.0}/setup.py +3 -1
- webscout-5.0/webscout/Agents/functioncall.py +142 -0
- webscout-5.0/webscout/Bing_search.py +124 -0
- webscout-5.0/webscout/DWEBS.py +157 -0
- webscout-5.0/webscout/Provider/Cloudflare.py +286 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/DiscordRocks.py +5 -4
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Farfalle.py +3 -3
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Llama3.py +3 -3
- webscout-5.0/webscout/Provider/PI.py +208 -0
- webscout-5.0/webscout/Provider/Youchat.py +247 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/__init__.py +16 -2
- webscout-5.0/webscout/Provider/felo_search.py +238 -0
- webscout-5.0/webscout/Provider/julius.py +263 -0
- webscout-5.0/webscout/Provider/turboseek.py +237 -0
- webscout-5.0/webscout/Provider/xdash.py +202 -0
- webscout-5.0/webscout/Provider/yep.py +258 -0
- {webscout-4.8 → webscout-5.0}/webscout/__init__.py +1 -59
- {webscout-4.8 → webscout-5.0/webscout.egg-info}/PKG-INFO +25 -74
- {webscout-4.8 → webscout-5.0}/webscout.egg-info/SOURCES.txt +10 -2
- {webscout-4.8 → webscout-5.0}/webscout.egg-info/requires.txt +2 -0
- webscout-4.8/webscout/Agents/functioncall.py +0 -186
- webscout-4.8/webscout/DWEBS.py +0 -793
- webscout-4.8/webscout/GoogleS.py +0 -342
- {webscout-4.8 → webscout-5.0}/LICENSE.md +0 -0
- {webscout-4.8 → webscout-5.0}/setup.cfg +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/AIauto.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/AIbase.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/AIutel.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Agents/Onlinesearcher.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Agents/__init__.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Bard.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Extra/__init__.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Extra/autollama.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Extra/gguf.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Extra/weather.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Extra/weather_ascii.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/LLM.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Local/__init__.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Local/_version.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Local/formats.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Local/model.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Local/rawdog.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Local/samplers.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Local/thread.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Local/utils.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Andi.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/BasedGPT.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Berlin4h.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Blackboxai.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Cohere.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/DARKAI.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Deepinfra.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Deepseek.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Gemini.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Groq.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Koboldai.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Llama.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/OLLAMA.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Openai.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Perplexity.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Phind.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/PizzaGPT.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Poe.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/RUBIKSAI.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/Reka.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/ThinkAnyAI.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/ai4chat.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/koala.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/liaobots.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/Provider/meta.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/YTdownloader.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/__main__.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/async_providers.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/cli.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/exceptions.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/g4f.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/models.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/tempid.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/transcriber.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/utils.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/version.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/voice.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/webai.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/webscout_search.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/webscout_search_async.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout/websx_search.py +0 -0
- {webscout-4.8 → webscout-5.0}/webscout.egg-info/dependency_links.txt +0 -0
- {webscout-4.8 → webscout-5.0}/webscout.egg-info/entry_points.txt +0 -0
- {webscout-4.8 → webscout-5.0}/webscout.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: webscout
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0
|
|
4
4
|
Summary: Search for anything using Google, DuckDuckGo, brave, qwant, phind.com, Contains AI models, can transcribe yt videos, temporary email and phone number generation, has TTS support, webai (terminal gpt and open interpreter) and offline LLMs and more
|
|
5
5
|
Author: OEvortex
|
|
6
6
|
Author-email: helpingai5@gmail.com
|
|
@@ -64,6 +64,8 @@ Requires-Dist: yaspin
|
|
|
64
64
|
Requires-Dist: pillow
|
|
65
65
|
Requires-Dist: requests_html
|
|
66
66
|
Requires-Dist: bson
|
|
67
|
+
Requires-Dist: cloudscraper
|
|
68
|
+
Requires-Dist: emoji
|
|
67
69
|
Provides-Extra: dev
|
|
68
70
|
Requires-Dist: ruff>=0.1.6; extra == "dev"
|
|
69
71
|
Requires-Dist: pytest>=7.4.2; extra == "dev"
|
|
@@ -208,7 +210,7 @@ python -m webscout --help
|
|
|
208
210
|
|
|
209
211
|
|
|
210
212
|
[Go To TOP](#TOP)
|
|
211
|
-
## YTdownloader
|
|
213
|
+
## YTdownloader
|
|
212
214
|
|
|
213
215
|
```python
|
|
214
216
|
from os import rename, getcwd
|
|
@@ -232,7 +234,7 @@ if __name__ == "__main__":
|
|
|
232
234
|
download_video("https://www.youtube.com/watch?v=c0tMvzB0OKw")
|
|
233
235
|
```
|
|
234
236
|
|
|
235
|
-
## Weather
|
|
237
|
+
## Weather
|
|
236
238
|
1. weather
|
|
237
239
|
```python
|
|
238
240
|
from webscout import weather as w
|
|
@@ -331,6 +333,7 @@ async def main() -> None:
|
|
|
331
333
|
if __name__ == '__main__':
|
|
332
334
|
asyncio.run(main())
|
|
333
335
|
```
|
|
336
|
+
|
|
334
337
|
## Transcriber
|
|
335
338
|
The transcriber function in webscout is a handy tool that transcribes YouTube videos. Here's an example code demonstrating its usage:
|
|
336
339
|
```python
|
|
@@ -387,77 +390,25 @@ if __name__ == "__main__":
|
|
|
387
390
|
main()
|
|
388
391
|
```
|
|
389
392
|
|
|
390
|
-
##
|
|
391
|
-
|
|
392
|
-
`DWEBS` is a standalone feature designed to perform advanced web searches with enhanced capabilities. It is particularly powerful in extracting relevant information directly from webpages and Search engine, focusing exclusively on text (web) searches. Unlike the `WEBS` , which provides a broader range of search functionalities, `DWEBS` is specifically tailored for in-depth web searches.
|
|
393
|
-
|
|
394
|
-
### Activating DWEBS
|
|
395
|
-
|
|
396
|
-
To utilize the `DWEBS` feature, you must first create an instance of the `DWEBS` . This is designed to be used independently of the `WEBS` , offering a focused approach to web searches.
|
|
397
|
-
|
|
398
|
-
### Point to remember before using `DWEBS`
|
|
399
|
-
As `DWEBS` is designed to extract relevant information directly from webpages and Search engine, It extracts html from webpages and saves them to folder named files
|
|
400
|
-
|
|
401
|
-
### Usage Example
|
|
402
|
-
|
|
403
|
-
Here's a basic example of how to use the `DWEBS` :
|
|
393
|
+
## GoogleS -- formerly DWEBS
|
|
404
394
|
```python
|
|
405
|
-
from webscout import
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
query_html_path = google_searcher.search(
|
|
412
|
-
query='HelpingAI-9B',
|
|
413
|
-
result_num=10,
|
|
414
|
-
safe=False,
|
|
415
|
-
overwrite=False,
|
|
416
|
-
)
|
|
417
|
-
|
|
418
|
-
# 2. Search Result Extraction
|
|
419
|
-
query_results_extractor = DWEBS.QueryResultsExtractor()
|
|
420
|
-
query_search_results = query_results_extractor.extract(query_html_path)
|
|
421
|
-
|
|
422
|
-
if extract_webpage:
|
|
423
|
-
print('---------------Batch Webpage Fetcher--------------------')
|
|
424
|
-
# 3. Batch Webpage Fetching
|
|
425
|
-
batch_webpage_fetcher = DWEBS.BatchWebpageFetcher()
|
|
426
|
-
urls = [query_extracts['url'] for query_extracts in query_search_results['query_results']]
|
|
427
|
-
url_and_html_path_list = batch_webpage_fetcher.fetch(
|
|
428
|
-
urls,
|
|
429
|
-
overwrite=False,
|
|
430
|
-
output_parent=query_search_results["query"],
|
|
431
|
-
)
|
|
432
|
-
|
|
433
|
-
print('---------------Batch Webpage Extractor--------------------')
|
|
434
|
-
# 4. Batch Webpage Content Extraction
|
|
435
|
-
batch_webpage_content_extractor = DWEBS.BatchWebpageContentExtractor()
|
|
436
|
-
webpageurls = [url_and_html['html_path'] for url_and_html in url_and_html_path_list]
|
|
437
|
-
html_path_and_extracted_content_list = batch_webpage_content_extractor.extract(webpageurls)
|
|
438
|
-
|
|
439
|
-
# 5. Printing Extracted Content
|
|
440
|
-
for html_path_and_extracted_content in html_path_and_extracted_content_list:
|
|
441
|
-
print(html_path_and_extracted_content['extracted_content'])
|
|
442
|
-
else:
|
|
443
|
-
# Print only search results if extract_webpage is False
|
|
444
|
-
for result in query_search_results['query_results']:
|
|
445
|
-
DWEBS.logger.mesg(
|
|
446
|
-
f"{result['title']}\n"
|
|
447
|
-
f" - {result['site']}\n"
|
|
448
|
-
f" - {result['url']}\n"
|
|
449
|
-
f" - {result['abstract']}\n"
|
|
450
|
-
f"\n"
|
|
451
|
-
)
|
|
452
|
-
|
|
453
|
-
DWEBS.logger.success(f"- {len(query_search_results['query_results'])} query results")
|
|
454
|
-
DWEBS.logger.success(f"- {len(query_search_results['related_questions'])} related questions")
|
|
455
|
-
|
|
456
|
-
# Example usage:
|
|
457
|
-
finalextractor(extract_webpage=True) # Extract webpage content
|
|
458
|
-
finalextractor(extract_webpage=False) # Skip webpage extraction and print search results only
|
|
459
|
-
|
|
395
|
+
from webscout import GoogleS
|
|
396
|
+
from rich import print
|
|
397
|
+
searcher = GoogleS()
|
|
398
|
+
results = searcher.search("HelpingAI-9B", max_results=20, extract_webpage_text=False, max_extract_characters=100)
|
|
399
|
+
for result in results:
|
|
400
|
+
print(result)
|
|
460
401
|
```
|
|
402
|
+
### BingS
|
|
403
|
+
```python
|
|
404
|
+
from webscout import BingS
|
|
405
|
+
from rich import print
|
|
406
|
+
searcher = BingS()
|
|
407
|
+
results = searcher.search("Python development tools", max_results=30)
|
|
408
|
+
for result in results:
|
|
409
|
+
print(result)
|
|
410
|
+
```
|
|
411
|
+
|
|
461
412
|
## Text-to-Speech:
|
|
462
413
|
```python
|
|
463
414
|
from webscout import play_audio
|
|
@@ -1406,7 +1357,7 @@ from webscout import AndiSearch
|
|
|
1406
1357
|
a = AndiSearch()
|
|
1407
1358
|
print(a.chat("HelpingAI-9B"))
|
|
1408
1359
|
```
|
|
1409
|
-
### Function calling-
|
|
1360
|
+
### Function calling-beta
|
|
1410
1361
|
```python
|
|
1411
1362
|
import json
|
|
1412
1363
|
import logging
|
|
@@ -1519,7 +1470,7 @@ if "error" not in function_call_data:
|
|
|
1519
1470
|
else:
|
|
1520
1471
|
print(f"Error: {function_call_data['error']}")
|
|
1521
1472
|
```
|
|
1522
|
-
### LLAMA3, pizzagpt, RUBIKSAI, Koala, Darkai, AI4Chat, Farfalle
|
|
1473
|
+
### LLAMA3, pizzagpt, RUBIKSAI, Koala, Darkai, AI4Chat, Farfalle, PIAI, Felo, XDASH, Julius, YouChat, YEPCHAT, Cloudflare, TurboSeek,
|
|
1523
1474
|
code similar to other provider
|
|
1524
1475
|
### `LLM`
|
|
1525
1476
|
```python
|
|
@@ -133,7 +133,7 @@ python -m webscout --help
|
|
|
133
133
|
|
|
134
134
|
|
|
135
135
|
[Go To TOP](#TOP)
|
|
136
|
-
## YTdownloader
|
|
136
|
+
## YTdownloader
|
|
137
137
|
|
|
138
138
|
```python
|
|
139
139
|
from os import rename, getcwd
|
|
@@ -157,7 +157,7 @@ if __name__ == "__main__":
|
|
|
157
157
|
download_video("https://www.youtube.com/watch?v=c0tMvzB0OKw")
|
|
158
158
|
```
|
|
159
159
|
|
|
160
|
-
## Weather
|
|
160
|
+
## Weather
|
|
161
161
|
1. weather
|
|
162
162
|
```python
|
|
163
163
|
from webscout import weather as w
|
|
@@ -256,6 +256,7 @@ async def main() -> None:
|
|
|
256
256
|
if __name__ == '__main__':
|
|
257
257
|
asyncio.run(main())
|
|
258
258
|
```
|
|
259
|
+
|
|
259
260
|
## Transcriber
|
|
260
261
|
The transcriber function in webscout is a handy tool that transcribes YouTube videos. Here's an example code demonstrating its usage:
|
|
261
262
|
```python
|
|
@@ -312,77 +313,25 @@ if __name__ == "__main__":
|
|
|
312
313
|
main()
|
|
313
314
|
```
|
|
314
315
|
|
|
315
|
-
##
|
|
316
|
-
|
|
317
|
-
`DWEBS` is a standalone feature designed to perform advanced web searches with enhanced capabilities. It is particularly powerful in extracting relevant information directly from webpages and Search engine, focusing exclusively on text (web) searches. Unlike the `WEBS` , which provides a broader range of search functionalities, `DWEBS` is specifically tailored for in-depth web searches.
|
|
318
|
-
|
|
319
|
-
### Activating DWEBS
|
|
320
|
-
|
|
321
|
-
To utilize the `DWEBS` feature, you must first create an instance of the `DWEBS` . This is designed to be used independently of the `WEBS` , offering a focused approach to web searches.
|
|
322
|
-
|
|
323
|
-
### Point to remember before using `DWEBS`
|
|
324
|
-
As `DWEBS` is designed to extract relevant information directly from webpages and Search engine, It extracts html from webpages and saves them to folder named files
|
|
325
|
-
|
|
326
|
-
### Usage Example
|
|
327
|
-
|
|
328
|
-
Here's a basic example of how to use the `DWEBS` :
|
|
316
|
+
## GoogleS -- formerly DWEBS
|
|
329
317
|
```python
|
|
330
|
-
from webscout import
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
query_html_path = google_searcher.search(
|
|
337
|
-
query='HelpingAI-9B',
|
|
338
|
-
result_num=10,
|
|
339
|
-
safe=False,
|
|
340
|
-
overwrite=False,
|
|
341
|
-
)
|
|
342
|
-
|
|
343
|
-
# 2. Search Result Extraction
|
|
344
|
-
query_results_extractor = DWEBS.QueryResultsExtractor()
|
|
345
|
-
query_search_results = query_results_extractor.extract(query_html_path)
|
|
346
|
-
|
|
347
|
-
if extract_webpage:
|
|
348
|
-
print('---------------Batch Webpage Fetcher--------------------')
|
|
349
|
-
# 3. Batch Webpage Fetching
|
|
350
|
-
batch_webpage_fetcher = DWEBS.BatchWebpageFetcher()
|
|
351
|
-
urls = [query_extracts['url'] for query_extracts in query_search_results['query_results']]
|
|
352
|
-
url_and_html_path_list = batch_webpage_fetcher.fetch(
|
|
353
|
-
urls,
|
|
354
|
-
overwrite=False,
|
|
355
|
-
output_parent=query_search_results["query"],
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
print('---------------Batch Webpage Extractor--------------------')
|
|
359
|
-
# 4. Batch Webpage Content Extraction
|
|
360
|
-
batch_webpage_content_extractor = DWEBS.BatchWebpageContentExtractor()
|
|
361
|
-
webpageurls = [url_and_html['html_path'] for url_and_html in url_and_html_path_list]
|
|
362
|
-
html_path_and_extracted_content_list = batch_webpage_content_extractor.extract(webpageurls)
|
|
363
|
-
|
|
364
|
-
# 5. Printing Extracted Content
|
|
365
|
-
for html_path_and_extracted_content in html_path_and_extracted_content_list:
|
|
366
|
-
print(html_path_and_extracted_content['extracted_content'])
|
|
367
|
-
else:
|
|
368
|
-
# Print only search results if extract_webpage is False
|
|
369
|
-
for result in query_search_results['query_results']:
|
|
370
|
-
DWEBS.logger.mesg(
|
|
371
|
-
f"{result['title']}\n"
|
|
372
|
-
f" - {result['site']}\n"
|
|
373
|
-
f" - {result['url']}\n"
|
|
374
|
-
f" - {result['abstract']}\n"
|
|
375
|
-
f"\n"
|
|
376
|
-
)
|
|
377
|
-
|
|
378
|
-
DWEBS.logger.success(f"- {len(query_search_results['query_results'])} query results")
|
|
379
|
-
DWEBS.logger.success(f"- {len(query_search_results['related_questions'])} related questions")
|
|
380
|
-
|
|
381
|
-
# Example usage:
|
|
382
|
-
finalextractor(extract_webpage=True) # Extract webpage content
|
|
383
|
-
finalextractor(extract_webpage=False) # Skip webpage extraction and print search results only
|
|
384
|
-
|
|
318
|
+
from webscout import GoogleS
|
|
319
|
+
from rich import print
|
|
320
|
+
searcher = GoogleS()
|
|
321
|
+
results = searcher.search("HelpingAI-9B", max_results=20, extract_webpage_text=False, max_extract_characters=100)
|
|
322
|
+
for result in results:
|
|
323
|
+
print(result)
|
|
385
324
|
```
|
|
325
|
+
### BingS
|
|
326
|
+
```python
|
|
327
|
+
from webscout import BingS
|
|
328
|
+
from rich import print
|
|
329
|
+
searcher = BingS()
|
|
330
|
+
results = searcher.search("Python development tools", max_results=30)
|
|
331
|
+
for result in results:
|
|
332
|
+
print(result)
|
|
333
|
+
```
|
|
334
|
+
|
|
386
335
|
## Text-to-Speech:
|
|
387
336
|
```python
|
|
388
337
|
from webscout import play_audio
|
|
@@ -1331,7 +1280,7 @@ from webscout import AndiSearch
|
|
|
1331
1280
|
a = AndiSearch()
|
|
1332
1281
|
print(a.chat("HelpingAI-9B"))
|
|
1333
1282
|
```
|
|
1334
|
-
### Function calling-
|
|
1283
|
+
### Function calling-beta
|
|
1335
1284
|
```python
|
|
1336
1285
|
import json
|
|
1337
1286
|
import logging
|
|
@@ -1444,7 +1393,7 @@ if "error" not in function_call_data:
|
|
|
1444
1393
|
else:
|
|
1445
1394
|
print(f"Error: {function_call_data['error']}")
|
|
1446
1395
|
```
|
|
1447
|
-
### LLAMA3, pizzagpt, RUBIKSAI, Koala, Darkai, AI4Chat, Farfalle
|
|
1396
|
+
### LLAMA3, pizzagpt, RUBIKSAI, Koala, Darkai, AI4Chat, Farfalle, PIAI, Felo, XDASH, Julius, YouChat, YEPCHAT, Cloudflare, TurboSeek,
|
|
1448
1397
|
code similar to other provider
|
|
1449
1398
|
### `LLM`
|
|
1450
1399
|
```python
|
|
@@ -5,7 +5,7 @@ with open("README.md", encoding="utf-8") as f:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="webscout",
|
|
8
|
-
version="
|
|
8
|
+
version="5.0",
|
|
9
9
|
description="Search for anything using Google, DuckDuckGo, brave, qwant, phind.com, Contains AI models, can transcribe yt videos, temporary email and phone number generation, has TTS support, webai (terminal gpt and open interpreter) and offline LLMs and more",
|
|
10
10
|
long_description=README,
|
|
11
11
|
long_description_content_type="text/markdown",
|
|
@@ -68,6 +68,8 @@ setup(
|
|
|
68
68
|
"pillow",
|
|
69
69
|
"requests_html",
|
|
70
70
|
"bson",
|
|
71
|
+
"cloudscraper",
|
|
72
|
+
"emoji"
|
|
71
73
|
],
|
|
72
74
|
entry_points={
|
|
73
75
|
"console_scripts": [
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from webscout import LLAMA3, WEBS
|
|
4
|
+
|
|
5
|
+
class FunctionCallingAgent:
|
|
6
|
+
def __init__(self, model: str = "llama3-8b",
|
|
7
|
+
system_prompt: str = 'You are a helpful assistant that will always answer what the user wants',
|
|
8
|
+
tools: list = None):
|
|
9
|
+
self.LLAMA3 = LLAMA3(model=model, system=system_prompt, timeout=300)
|
|
10
|
+
self.tools = tools if tools is not None else []
|
|
11
|
+
self.webs = WEBS()
|
|
12
|
+
|
|
13
|
+
def function_call_handler(self, message_text: str) -> dict:
|
|
14
|
+
system_message = self._generate_system_message(message_text)
|
|
15
|
+
response = self.LLAMA3.chat(system_message)
|
|
16
|
+
# logging.info(f"Raw response: {response}")
|
|
17
|
+
return self._parse_function_call(response)
|
|
18
|
+
|
|
19
|
+
def _generate_system_message(self, user_message: str) -> str:
|
|
20
|
+
tools_description = '\n'.join([f"- {tool['function']['name']}: {tool['function'].get('description', '')}" for tool in self.tools])
|
|
21
|
+
return (
|
|
22
|
+
"You are an AI assistant capable of understanding user requests and using tools to fulfill them. "
|
|
23
|
+
"Always respond using the JSON format specified below, even if you're not sure about the answer. "
|
|
24
|
+
f"Available tools:\n{tools_description}\n\n"
|
|
25
|
+
"Instructions:\n"
|
|
26
|
+
"1. Analyze the user's request.\n"
|
|
27
|
+
"2. Choose the most appropriate tool based on the request.\n"
|
|
28
|
+
"3. Respond ONLY with a JSON object in this exact format:\n"
|
|
29
|
+
"{\n"
|
|
30
|
+
' "tool_name": "name_of_the_tool",\n'
|
|
31
|
+
' "tool_input": {\n'
|
|
32
|
+
' "param1": "value1",\n'
|
|
33
|
+
' "param2": "value2"\n'
|
|
34
|
+
" }\n"
|
|
35
|
+
"}\n\n"
|
|
36
|
+
"If you can't determine a suitable tool, use the 'general_ai' tool with the user's message as the 'question' parameter.\n\n"
|
|
37
|
+
f"User request: {user_message}\n\n"
|
|
38
|
+
"Your response (in JSON format):"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def _parse_function_call(self, response: str) -> dict:
|
|
42
|
+
try:
|
|
43
|
+
# Find the JSON-like part of the response
|
|
44
|
+
start_idx = response.find("{")
|
|
45
|
+
end_idx = response.rfind("}") + 1
|
|
46
|
+
|
|
47
|
+
if start_idx == -1 or end_idx == -1:
|
|
48
|
+
raise ValueError("No valid JSON structure found in the response.")
|
|
49
|
+
|
|
50
|
+
response_json_str = response[start_idx:end_idx]
|
|
51
|
+
|
|
52
|
+
# Attempt to load the JSON string
|
|
53
|
+
return json.loads(response_json_str)
|
|
54
|
+
|
|
55
|
+
except (ValueError, json.JSONDecodeError) as e:
|
|
56
|
+
logging.error(f"Error parsing function call: {e}")
|
|
57
|
+
return {"error": str(e)}
|
|
58
|
+
|
|
59
|
+
def execute_function(self, function_call_data: dict) -> str:
|
|
60
|
+
function_name = function_call_data.get("tool_name")
|
|
61
|
+
arguments = function_call_data.get("tool_input", {})
|
|
62
|
+
|
|
63
|
+
if not isinstance(arguments, dict):
|
|
64
|
+
logging.error("Invalid arguments format.")
|
|
65
|
+
return "Invalid arguments format."
|
|
66
|
+
|
|
67
|
+
logging.info(f"Executing function: {function_name} with arguments: {arguments}")
|
|
68
|
+
|
|
69
|
+
# if function_name == "web_search":
|
|
70
|
+
# return self._handle_web_search(arguments)
|
|
71
|
+
# elif function_name == "general_ai":
|
|
72
|
+
# return self._handle_general_ai(arguments)
|
|
73
|
+
# else:
|
|
74
|
+
# return f"Function '{function_name}' is not implemented."
|
|
75
|
+
|
|
76
|
+
# def _handle_web_search(self, arguments: dict) -> str:
|
|
77
|
+
# query = arguments.get("query")
|
|
78
|
+
# if not query:
|
|
79
|
+
# return "Please provide a search query."
|
|
80
|
+
|
|
81
|
+
# search_results = self.webs.text(query, max_results=3)
|
|
82
|
+
# formatted_results = "\n\n".join(
|
|
83
|
+
# f"{i+1}. {result['title']}\n{result['body']}\nURL: {result['href']}"
|
|
84
|
+
# for i, result in enumerate(search_results)
|
|
85
|
+
# )
|
|
86
|
+
# return f"Here's what I found:\n\n{formatted_results}"
|
|
87
|
+
|
|
88
|
+
# def _handle_general_ai(self, arguments: dict) -> str:
|
|
89
|
+
# question = arguments.get("question")
|
|
90
|
+
# if not question:
|
|
91
|
+
# return "Please provide a question for the AI to answer."
|
|
92
|
+
|
|
93
|
+
# response = self.LLAMA3.chat(question)
|
|
94
|
+
# return response
|
|
95
|
+
|
|
96
|
+
# Example usage
|
|
97
|
+
if __name__ == "__main__":
|
|
98
|
+
tools = [
|
|
99
|
+
{
|
|
100
|
+
"type": "function",
|
|
101
|
+
"function": {
|
|
102
|
+
"name": "web_search",
|
|
103
|
+
"description": "Search query on Google",
|
|
104
|
+
"parameters": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"properties": {
|
|
107
|
+
"query": {
|
|
108
|
+
"type": "string",
|
|
109
|
+
"description": "web search query"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"required": ["query"]
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "function",
|
|
118
|
+
"function": {
|
|
119
|
+
"name": "general_ai",
|
|
120
|
+
"description": "Use AI to answer a general question",
|
|
121
|
+
"parameters": {
|
|
122
|
+
"type": "object",
|
|
123
|
+
"properties": {
|
|
124
|
+
"question": {
|
|
125
|
+
"type": "string",
|
|
126
|
+
"description": "The question to be answered by the AI"
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"required": ["question"]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
agent = FunctionCallingAgent(tools=tools)
|
|
136
|
+
message = "open yt"
|
|
137
|
+
function_call_data = agent.function_call_handler(message)
|
|
138
|
+
print(f"Function Call Data: {function_call_data}")
|
|
139
|
+
|
|
140
|
+
if "error" not in function_call_data:
|
|
141
|
+
result = agent.execute_function(function_call_data)
|
|
142
|
+
print(f"Function Execution Result: {result}")
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from bs4 import BeautifulSoup
|
|
2
|
+
import requests
|
|
3
|
+
from typing import Dict, List, Optional, Union
|
|
4
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
5
|
+
from urllib.parse import urlparse
|
|
6
|
+
from termcolor import colored
|
|
7
|
+
import time
|
|
8
|
+
import random
|
|
9
|
+
|
|
10
|
+
class BingS:
|
|
11
|
+
"""Bing search class to get search results from bing.com."""
|
|
12
|
+
|
|
13
|
+
_executor: ThreadPoolExecutor = ThreadPoolExecutor(max_workers=10)
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
headers: Optional[Dict[str, str]] = None,
|
|
18
|
+
proxy: Optional[str] = None,
|
|
19
|
+
timeout: Optional[int] = 10,
|
|
20
|
+
) -> None:
|
|
21
|
+
"""Initialize the BingS object."""
|
|
22
|
+
self.proxy: Optional[str] = proxy
|
|
23
|
+
self.headers = headers if headers else {
|
|
24
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.62"
|
|
25
|
+
}
|
|
26
|
+
self.headers["Referer"] = "https://www.bing.com/"
|
|
27
|
+
self.client = requests.Session()
|
|
28
|
+
self.client.headers.update(self.headers)
|
|
29
|
+
self.client.proxies.update({"http": self.proxy, "https": self.proxy})
|
|
30
|
+
self.timeout = timeout
|
|
31
|
+
|
|
32
|
+
def __enter__(self) -> "BingS":
|
|
33
|
+
return self
|
|
34
|
+
|
|
35
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
36
|
+
self.client.close()
|
|
37
|
+
|
|
38
|
+
def _get_url(
|
|
39
|
+
self,
|
|
40
|
+
method: str,
|
|
41
|
+
url: str,
|
|
42
|
+
params: Optional[Dict[str, str]] = None,
|
|
43
|
+
data: Optional[Union[Dict[str, str], bytes]] = None,
|
|
44
|
+
) -> bytes:
|
|
45
|
+
try:
|
|
46
|
+
resp = self.client.request(method, url, params=params, data=data, timeout=self.timeout)
|
|
47
|
+
except Exception as ex:
|
|
48
|
+
raise Exception(f"{url} {type(ex).__name__}: {ex}") from ex
|
|
49
|
+
if resp.status_code == 200:
|
|
50
|
+
return resp.content
|
|
51
|
+
raise Exception(f"{resp.url} returned status code {resp.status_code}. {params=} {data=}")
|
|
52
|
+
|
|
53
|
+
def search(
|
|
54
|
+
self,
|
|
55
|
+
keywords: str,
|
|
56
|
+
region: str = "us-EN", # Bing uses us-EN
|
|
57
|
+
lang: str = "en",
|
|
58
|
+
safe: str = "off",
|
|
59
|
+
timelimit: Optional[str] = None, # Not directly supported by Bing
|
|
60
|
+
max_results: Optional[int] = None,
|
|
61
|
+
) -> List[Dict[str, str]]:
|
|
62
|
+
"""Bing text search."""
|
|
63
|
+
assert keywords, "keywords is mandatory"
|
|
64
|
+
|
|
65
|
+
results = []
|
|
66
|
+
start = 1 # Bing uses 1-based indexing for pages
|
|
67
|
+
while len(results) < (max_results or float('inf')):
|
|
68
|
+
params = {
|
|
69
|
+
"q": keywords,
|
|
70
|
+
"count": 10, # Number of results per page
|
|
71
|
+
"mkt": region,
|
|
72
|
+
"setlang": lang,
|
|
73
|
+
"safeSearch": safe,
|
|
74
|
+
"first": start, # Bing uses 'first' for pagination
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
resp_content = self._get_url("GET", "https://www.bing.com/search", params=params)
|
|
79
|
+
soup = BeautifulSoup(resp_content, "html.parser")
|
|
80
|
+
result_block = soup.find_all("li", class_="b_algo")
|
|
81
|
+
|
|
82
|
+
if not result_block:
|
|
83
|
+
break
|
|
84
|
+
|
|
85
|
+
for result in result_block:
|
|
86
|
+
try:
|
|
87
|
+
link = result.find("a", href=True)
|
|
88
|
+
if link:
|
|
89
|
+
initial_url = link["href"]
|
|
90
|
+
|
|
91
|
+
title = result.find("h2").text if result.find("h2") else ""
|
|
92
|
+
description = result.find("p").text.strip() if result.find("p") else "" # Strip whitespace
|
|
93
|
+
|
|
94
|
+
# Remove 'WEB' prefix if present
|
|
95
|
+
if description.startswith("WEB"):
|
|
96
|
+
description = description[4:] # Skip the first 4 characters ('WEB ')
|
|
97
|
+
|
|
98
|
+
results.append({
|
|
99
|
+
"title": title,
|
|
100
|
+
"href": initial_url,
|
|
101
|
+
"abstract": description,
|
|
102
|
+
"index": len(results),
|
|
103
|
+
"type": "web",
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
if len(results) >= max_results:
|
|
107
|
+
return results
|
|
108
|
+
|
|
109
|
+
except Exception as e:
|
|
110
|
+
print(f"Error extracting result: {e}")
|
|
111
|
+
|
|
112
|
+
except Exception as e:
|
|
113
|
+
print(f"Error fetching URL: {e}")
|
|
114
|
+
|
|
115
|
+
start += 10
|
|
116
|
+
|
|
117
|
+
return results
|
|
118
|
+
|
|
119
|
+
if __name__ == "__main__":
|
|
120
|
+
from rich import print
|
|
121
|
+
searcher = BingS()
|
|
122
|
+
results = searcher.search("Python development tools", max_results=30)
|
|
123
|
+
for result in results:
|
|
124
|
+
print(result)
|