webscout 8.2.7__py3-none-any.whl โ 8.2.8__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/AIauto.py +1 -1
- webscout/AIutel.py +298 -249
- webscout/Extra/Act.md +309 -0
- webscout/Extra/GitToolkit/__init__.py +10 -0
- webscout/Extra/GitToolkit/gitapi/README.md +110 -0
- webscout/Extra/GitToolkit/gitapi/__init__.py +12 -0
- webscout/Extra/GitToolkit/gitapi/repository.py +195 -0
- webscout/Extra/GitToolkit/gitapi/user.py +96 -0
- webscout/Extra/GitToolkit/gitapi/utils.py +62 -0
- webscout/Extra/YTToolkit/README.md +375 -0
- webscout/Extra/YTToolkit/YTdownloader.py +957 -0
- webscout/Extra/YTToolkit/__init__.py +3 -0
- webscout/Extra/YTToolkit/transcriber.py +476 -0
- webscout/Extra/YTToolkit/ytapi/README.md +44 -0
- webscout/Extra/YTToolkit/ytapi/__init__.py +6 -0
- webscout/Extra/YTToolkit/ytapi/channel.py +307 -0
- webscout/Extra/YTToolkit/ytapi/errors.py +13 -0
- webscout/Extra/YTToolkit/ytapi/extras.py +118 -0
- webscout/Extra/YTToolkit/ytapi/https.py +88 -0
- webscout/Extra/YTToolkit/ytapi/patterns.py +61 -0
- webscout/Extra/YTToolkit/ytapi/playlist.py +59 -0
- webscout/Extra/YTToolkit/ytapi/pool.py +8 -0
- webscout/Extra/YTToolkit/ytapi/query.py +40 -0
- webscout/Extra/YTToolkit/ytapi/stream.py +63 -0
- webscout/Extra/YTToolkit/ytapi/utils.py +62 -0
- webscout/Extra/YTToolkit/ytapi/video.py +232 -0
- webscout/Extra/__init__.py +7 -0
- webscout/Extra/autocoder/__init__.py +9 -0
- webscout/Extra/autocoder/autocoder.py +1105 -0
- webscout/Extra/autocoder/autocoder_utiles.py +332 -0
- webscout/Extra/gguf.md +430 -0
- webscout/Extra/gguf.py +684 -0
- webscout/Extra/tempmail/README.md +488 -0
- webscout/Extra/tempmail/__init__.py +28 -0
- webscout/Extra/tempmail/async_utils.py +141 -0
- webscout/Extra/tempmail/base.py +161 -0
- webscout/Extra/tempmail/cli.py +187 -0
- webscout/Extra/tempmail/emailnator.py +84 -0
- webscout/Extra/tempmail/mail_tm.py +361 -0
- webscout/Extra/tempmail/temp_mail_io.py +292 -0
- webscout/Extra/weather.md +281 -0
- webscout/Extra/weather.py +194 -0
- webscout/Extra/weather_ascii.py +76 -0
- webscout/Litlogger/Readme.md +175 -0
- webscout/Litlogger/__init__.py +67 -0
- webscout/Litlogger/core/__init__.py +6 -0
- webscout/Litlogger/core/level.py +23 -0
- webscout/Litlogger/core/logger.py +165 -0
- webscout/Litlogger/handlers/__init__.py +12 -0
- webscout/Litlogger/handlers/console.py +33 -0
- webscout/Litlogger/handlers/file.py +143 -0
- webscout/Litlogger/handlers/network.py +173 -0
- webscout/Litlogger/styles/__init__.py +7 -0
- webscout/Litlogger/styles/colors.py +249 -0
- webscout/Litlogger/styles/formats.py +458 -0
- webscout/Litlogger/styles/text.py +87 -0
- webscout/Litlogger/utils/__init__.py +6 -0
- webscout/Litlogger/utils/detectors.py +153 -0
- webscout/Litlogger/utils/formatters.py +200 -0
- webscout/Provider/AI21.py +177 -0
- webscout/Provider/AISEARCH/DeepFind.py +254 -0
- webscout/Provider/AISEARCH/Perplexity.py +359 -0
- webscout/Provider/AISEARCH/README.md +279 -0
- webscout/Provider/AISEARCH/__init__.py +9 -0
- webscout/Provider/AISEARCH/felo_search.py +228 -0
- webscout/Provider/AISEARCH/genspark_search.py +350 -0
- webscout/Provider/AISEARCH/hika_search.py +198 -0
- webscout/Provider/AISEARCH/iask_search.py +436 -0
- webscout/Provider/AISEARCH/monica_search.py +246 -0
- webscout/Provider/AISEARCH/scira_search.py +324 -0
- webscout/Provider/AISEARCH/webpilotai_search.py +281 -0
- webscout/Provider/Aitopia.py +316 -0
- webscout/Provider/AllenAI.py +440 -0
- webscout/Provider/Andi.py +228 -0
- webscout/Provider/Blackboxai.py +673 -0
- webscout/Provider/ChatGPTClone.py +237 -0
- webscout/Provider/ChatGPTGratis.py +194 -0
- webscout/Provider/ChatSandbox.py +342 -0
- webscout/Provider/Cloudflare.py +324 -0
- webscout/Provider/Cohere.py +208 -0
- webscout/Provider/Deepinfra.py +340 -0
- webscout/Provider/ExaAI.py +261 -0
- webscout/Provider/ExaChat.py +358 -0
- webscout/Provider/Flowith.py +217 -0
- webscout/Provider/FreeGemini.py +250 -0
- webscout/Provider/Gemini.py +169 -0
- webscout/Provider/GithubChat.py +370 -0
- webscout/Provider/GizAI.py +295 -0
- webscout/Provider/Glider.py +225 -0
- webscout/Provider/Groq.py +801 -0
- webscout/Provider/HF_space/__init__.py +0 -0
- webscout/Provider/HF_space/qwen_qwen2.py +206 -0
- webscout/Provider/HeckAI.py +285 -0
- webscout/Provider/HuggingFaceChat.py +469 -0
- webscout/Provider/Hunyuan.py +283 -0
- webscout/Provider/Jadve.py +291 -0
- webscout/Provider/Koboldai.py +384 -0
- webscout/Provider/LambdaChat.py +411 -0
- webscout/Provider/Llama3.py +259 -0
- webscout/Provider/MCPCore.py +315 -0
- webscout/Provider/Marcus.py +198 -0
- webscout/Provider/Nemotron.py +218 -0
- webscout/Provider/Netwrck.py +270 -0
- webscout/Provider/OLLAMA.py +396 -0
- webscout/Provider/OPENAI/BLACKBOXAI.py +735 -0
- webscout/Provider/OPENAI/Cloudflare.py +378 -0
- webscout/Provider/OPENAI/FreeGemini.py +282 -0
- webscout/Provider/OPENAI/NEMOTRON.py +244 -0
- webscout/Provider/OPENAI/README.md +1253 -0
- webscout/Provider/OPENAI/__init__.py +36 -0
- webscout/Provider/OPENAI/ai4chat.py +293 -0
- webscout/Provider/OPENAI/api.py +810 -0
- webscout/Provider/OPENAI/base.py +249 -0
- webscout/Provider/OPENAI/c4ai.py +373 -0
- webscout/Provider/OPENAI/chatgpt.py +556 -0
- webscout/Provider/OPENAI/chatgptclone.py +488 -0
- webscout/Provider/OPENAI/chatsandbox.py +172 -0
- webscout/Provider/OPENAI/deepinfra.py +319 -0
- webscout/Provider/OPENAI/e2b.py +1356 -0
- webscout/Provider/OPENAI/exaai.py +411 -0
- webscout/Provider/OPENAI/exachat.py +443 -0
- webscout/Provider/OPENAI/flowith.py +162 -0
- webscout/Provider/OPENAI/freeaichat.py +359 -0
- webscout/Provider/OPENAI/glider.py +323 -0
- webscout/Provider/OPENAI/groq.py +361 -0
- webscout/Provider/OPENAI/heckai.py +307 -0
- webscout/Provider/OPENAI/llmchatco.py +335 -0
- webscout/Provider/OPENAI/mcpcore.py +383 -0
- webscout/Provider/OPENAI/multichat.py +376 -0
- webscout/Provider/OPENAI/netwrck.py +356 -0
- webscout/Provider/OPENAI/opkfc.py +496 -0
- webscout/Provider/OPENAI/scirachat.py +471 -0
- webscout/Provider/OPENAI/sonus.py +303 -0
- webscout/Provider/OPENAI/standardinput.py +433 -0
- webscout/Provider/OPENAI/textpollinations.py +339 -0
- webscout/Provider/OPENAI/toolbaz.py +413 -0
- webscout/Provider/OPENAI/typefully.py +355 -0
- webscout/Provider/OPENAI/typegpt.py +358 -0
- webscout/Provider/OPENAI/uncovrAI.py +462 -0
- webscout/Provider/OPENAI/utils.py +307 -0
- webscout/Provider/OPENAI/venice.py +425 -0
- webscout/Provider/OPENAI/wisecat.py +381 -0
- webscout/Provider/OPENAI/writecream.py +163 -0
- webscout/Provider/OPENAI/x0gpt.py +378 -0
- webscout/Provider/OPENAI/yep.py +356 -0
- webscout/Provider/OpenGPT.py +209 -0
- webscout/Provider/Openai.py +496 -0
- webscout/Provider/PI.py +429 -0
- webscout/Provider/Perplexitylabs.py +415 -0
- webscout/Provider/QwenLM.py +254 -0
- webscout/Provider/Reka.py +214 -0
- webscout/Provider/StandardInput.py +290 -0
- webscout/Provider/TTI/AiForce/README.md +159 -0
- webscout/Provider/TTI/AiForce/__init__.py +22 -0
- webscout/Provider/TTI/AiForce/async_aiforce.py +224 -0
- webscout/Provider/TTI/AiForce/sync_aiforce.py +245 -0
- webscout/Provider/TTI/FreeAIPlayground/README.md +99 -0
- webscout/Provider/TTI/FreeAIPlayground/__init__.py +9 -0
- webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +181 -0
- webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +180 -0
- webscout/Provider/TTI/ImgSys/README.md +174 -0
- webscout/Provider/TTI/ImgSys/__init__.py +23 -0
- webscout/Provider/TTI/ImgSys/async_imgsys.py +202 -0
- webscout/Provider/TTI/ImgSys/sync_imgsys.py +195 -0
- webscout/Provider/TTI/MagicStudio/README.md +101 -0
- webscout/Provider/TTI/MagicStudio/__init__.py +2 -0
- webscout/Provider/TTI/MagicStudio/async_magicstudio.py +111 -0
- webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +109 -0
- webscout/Provider/TTI/Nexra/README.md +155 -0
- webscout/Provider/TTI/Nexra/__init__.py +22 -0
- webscout/Provider/TTI/Nexra/async_nexra.py +286 -0
- webscout/Provider/TTI/Nexra/sync_nexra.py +258 -0
- webscout/Provider/TTI/PollinationsAI/README.md +146 -0
- webscout/Provider/TTI/PollinationsAI/__init__.py +23 -0
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +311 -0
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +265 -0
- webscout/Provider/TTI/README.md +128 -0
- webscout/Provider/TTI/__init__.py +12 -0
- webscout/Provider/TTI/aiarta/README.md +134 -0
- webscout/Provider/TTI/aiarta/__init__.py +2 -0
- webscout/Provider/TTI/aiarta/async_aiarta.py +482 -0
- webscout/Provider/TTI/aiarta/sync_aiarta.py +440 -0
- webscout/Provider/TTI/artbit/README.md +100 -0
- webscout/Provider/TTI/artbit/__init__.py +22 -0
- webscout/Provider/TTI/artbit/async_artbit.py +155 -0
- webscout/Provider/TTI/artbit/sync_artbit.py +148 -0
- webscout/Provider/TTI/fastflux/README.md +129 -0
- webscout/Provider/TTI/fastflux/__init__.py +22 -0
- webscout/Provider/TTI/fastflux/async_fastflux.py +261 -0
- webscout/Provider/TTI/fastflux/sync_fastflux.py +252 -0
- webscout/Provider/TTI/huggingface/README.md +114 -0
- webscout/Provider/TTI/huggingface/__init__.py +22 -0
- webscout/Provider/TTI/huggingface/async_huggingface.py +199 -0
- webscout/Provider/TTI/huggingface/sync_huggingface.py +195 -0
- webscout/Provider/TTI/piclumen/README.md +161 -0
- webscout/Provider/TTI/piclumen/__init__.py +23 -0
- webscout/Provider/TTI/piclumen/async_piclumen.py +268 -0
- webscout/Provider/TTI/piclumen/sync_piclumen.py +233 -0
- webscout/Provider/TTI/pixelmuse/README.md +79 -0
- webscout/Provider/TTI/pixelmuse/__init__.py +4 -0
- webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +249 -0
- webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +182 -0
- webscout/Provider/TTI/talkai/README.md +139 -0
- webscout/Provider/TTI/talkai/__init__.py +4 -0
- webscout/Provider/TTI/talkai/async_talkai.py +229 -0
- webscout/Provider/TTI/talkai/sync_talkai.py +207 -0
- webscout/Provider/TTS/README.md +192 -0
- webscout/Provider/TTS/__init__.py +9 -0
- webscout/Provider/TTS/base.py +159 -0
- webscout/Provider/TTS/deepgram.py +156 -0
- webscout/Provider/TTS/elevenlabs.py +111 -0
- webscout/Provider/TTS/gesserit.py +128 -0
- webscout/Provider/TTS/murfai.py +113 -0
- webscout/Provider/TTS/parler.py +111 -0
- webscout/Provider/TTS/speechma.py +580 -0
- webscout/Provider/TTS/sthir.py +94 -0
- webscout/Provider/TTS/streamElements.py +333 -0
- webscout/Provider/TTS/utils.py +280 -0
- webscout/Provider/TeachAnything.py +229 -0
- webscout/Provider/TextPollinationsAI.py +308 -0
- webscout/Provider/TwoAI.py +280 -0
- webscout/Provider/TypliAI.py +305 -0
- webscout/Provider/UNFINISHED/ChatHub.py +209 -0
- webscout/Provider/UNFINISHED/Youchat.py +330 -0
- webscout/Provider/UNFINISHED/liner_api_request.py +263 -0
- webscout/Provider/UNFINISHED/oivscode.py +351 -0
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -0
- webscout/Provider/Venice.py +258 -0
- webscout/Provider/VercelAI.py +253 -0
- webscout/Provider/WiseCat.py +233 -0
- webscout/Provider/WrDoChat.py +370 -0
- webscout/Provider/Writecream.py +246 -0
- webscout/Provider/WritingMate.py +269 -0
- webscout/Provider/__init__.py +172 -0
- webscout/Provider/ai4chat.py +149 -0
- webscout/Provider/akashgpt.py +335 -0
- webscout/Provider/asksteve.py +220 -0
- webscout/Provider/cerebras.py +290 -0
- webscout/Provider/chatglm.py +215 -0
- webscout/Provider/cleeai.py +213 -0
- webscout/Provider/copilot.py +425 -0
- webscout/Provider/elmo.py +283 -0
- webscout/Provider/freeaichat.py +285 -0
- webscout/Provider/geminiapi.py +208 -0
- webscout/Provider/granite.py +235 -0
- webscout/Provider/hermes.py +266 -0
- webscout/Provider/julius.py +223 -0
- webscout/Provider/koala.py +170 -0
- webscout/Provider/learnfastai.py +325 -0
- webscout/Provider/llama3mitril.py +215 -0
- webscout/Provider/llmchat.py +258 -0
- webscout/Provider/llmchatco.py +306 -0
- webscout/Provider/lmarena.py +198 -0
- webscout/Provider/meta.py +801 -0
- webscout/Provider/multichat.py +364 -0
- webscout/Provider/samurai.py +223 -0
- webscout/Provider/scira_chat.py +299 -0
- webscout/Provider/scnet.py +243 -0
- webscout/Provider/searchchat.py +292 -0
- webscout/Provider/sonus.py +258 -0
- webscout/Provider/talkai.py +194 -0
- webscout/Provider/toolbaz.py +353 -0
- webscout/Provider/turboseek.py +266 -0
- webscout/Provider/typefully.py +202 -0
- webscout/Provider/typegpt.py +289 -0
- webscout/Provider/uncovr.py +368 -0
- webscout/Provider/x0gpt.py +299 -0
- webscout/Provider/yep.py +389 -0
- webscout/__init__.py +4 -2
- webscout/cli.py +3 -28
- webscout/conversation.py +35 -35
- webscout/litagent/Readme.md +276 -0
- webscout/litagent/__init__.py +29 -0
- webscout/litagent/agent.py +455 -0
- webscout/litagent/constants.py +60 -0
- webscout/litprinter/__init__.py +59 -0
- webscout/scout/README.md +402 -0
- webscout/scout/__init__.py +8 -0
- webscout/scout/core/__init__.py +7 -0
- webscout/scout/core/crawler.py +140 -0
- webscout/scout/core/scout.py +568 -0
- webscout/scout/core/search_result.py +96 -0
- webscout/scout/core/text_analyzer.py +63 -0
- webscout/scout/core/text_utils.py +277 -0
- webscout/scout/core/web_analyzer.py +52 -0
- webscout/scout/element.py +460 -0
- webscout/scout/parsers/__init__.py +69 -0
- webscout/scout/parsers/html5lib_parser.py +172 -0
- webscout/scout/parsers/html_parser.py +236 -0
- webscout/scout/parsers/lxml_parser.py +178 -0
- webscout/scout/utils.py +37 -0
- webscout/swiftcli/Readme.md +323 -0
- webscout/swiftcli/__init__.py +95 -0
- webscout/swiftcli/core/__init__.py +7 -0
- webscout/swiftcli/core/cli.py +297 -0
- webscout/swiftcli/core/context.py +104 -0
- webscout/swiftcli/core/group.py +241 -0
- webscout/swiftcli/decorators/__init__.py +28 -0
- webscout/swiftcli/decorators/command.py +221 -0
- webscout/swiftcli/decorators/options.py +220 -0
- webscout/swiftcli/decorators/output.py +252 -0
- webscout/swiftcli/exceptions.py +21 -0
- webscout/swiftcli/plugins/__init__.py +9 -0
- webscout/swiftcli/plugins/base.py +135 -0
- webscout/swiftcli/plugins/manager.py +262 -0
- webscout/swiftcli/utils/__init__.py +59 -0
- webscout/swiftcli/utils/formatting.py +252 -0
- webscout/swiftcli/utils/parsing.py +267 -0
- webscout/version.py +1 -1
- webscout/webscout_search.py +2 -182
- webscout/webscout_search_async.py +1 -179
- webscout/zeroart/README.md +89 -0
- webscout/zeroart/__init__.py +135 -0
- webscout/zeroart/base.py +66 -0
- webscout/zeroart/effects.py +101 -0
- webscout/zeroart/fonts.py +1239 -0
- {webscout-8.2.7.dist-info โ webscout-8.2.8.dist-info}/METADATA +115 -60
- webscout-8.2.8.dist-info/RECORD +334 -0
- {webscout-8.2.7.dist-info โ webscout-8.2.8.dist-info}/WHEEL +1 -1
- webscout-8.2.7.dist-info/RECORD +0 -26
- {webscout-8.2.7.dist-info โ webscout-8.2.8.dist-info}/entry_points.txt +0 -0
- {webscout-8.2.7.dist-info โ webscout-8.2.8.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.2.7.dist-info โ webscout-8.2.8.dist-info}/top_level.txt +0 -0
webscout/__init__.py
CHANGED
|
@@ -26,9 +26,11 @@ __repo__ = "https://github.com/OE-LUCIFER/Webscout"
|
|
|
26
26
|
# Add update checker
|
|
27
27
|
from .update_checker import check_for_updates
|
|
28
28
|
try:
|
|
29
|
-
check_for_updates()
|
|
29
|
+
update_message = check_for_updates()
|
|
30
|
+
if update_message:
|
|
31
|
+
print(update_message)
|
|
30
32
|
except Exception:
|
|
31
|
-
pass # Silently handle any update check errors
|
|
33
|
+
pass # Silently handle any update check errorslently handle any update check errors
|
|
32
34
|
|
|
33
35
|
import logging
|
|
34
36
|
logging.getLogger("webscout").addHandler(logging.NullHandler())
|
webscout/cli.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from .swiftcli import CLI, option
|
|
3
|
-
from .webscout_search import WEBS
|
|
3
|
+
from .webscout_search import WEBS # Import the WEBS class from webscout_search
|
|
4
4
|
from .DWEBS import GoogleSearch # Import GoogleSearch from DWEBS
|
|
5
5
|
from .yep_search import YepSearch # Import YepSearch from yep_search
|
|
6
6
|
from .version import __version__
|
|
@@ -48,32 +48,7 @@ def version():
|
|
|
48
48
|
"""Show the version of webscout."""
|
|
49
49
|
print(f"webscout version: {__version__}")
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
@option("--proxy", help="Proxy URL to use for requests")
|
|
53
|
-
@option("--model", "-m", help="AI model to use", default="gpt-4o-mini", type=str)
|
|
54
|
-
@option("--timeout", "-t", help="Timeout value for requests", type=int, default=10)
|
|
55
|
-
def chat(proxy: str = None, model: str = "gpt-4o-mini", timeout: int = 10):
|
|
56
|
-
"""Interactive AI chat using DuckDuckGo's AI."""
|
|
57
|
-
webs = WEBS(proxy=proxy, timeout=timeout)
|
|
58
|
-
|
|
59
|
-
print(f"Using model: {model}")
|
|
60
|
-
print("Type your message and press Enter. Press Ctrl+C or type 'exit' to quit.\n")
|
|
61
|
-
|
|
62
|
-
try:
|
|
63
|
-
while True:
|
|
64
|
-
try:
|
|
65
|
-
user_input = input(">>> ").strip()
|
|
66
|
-
if not user_input or user_input.lower() in ['exit', 'quit']:
|
|
67
|
-
break
|
|
68
|
-
|
|
69
|
-
response = webs.chat(keywords=user_input, model=model)
|
|
70
|
-
print(f"\nAI: {response}\n")
|
|
71
|
-
|
|
72
|
-
except Exception as e:
|
|
73
|
-
print(f"Error: {str(e)}\n")
|
|
74
|
-
|
|
75
|
-
except KeyboardInterrupt:
|
|
76
|
-
print("\nChat session interrupted. Exiting...")
|
|
51
|
+
|
|
77
52
|
|
|
78
53
|
@app.command()
|
|
79
54
|
@option("--keywords", "-k", help="Search keywords", required=True)
|
|
@@ -546,4 +521,4 @@ def main():
|
|
|
546
521
|
sys.exit(1)
|
|
547
522
|
|
|
548
523
|
if __name__ == "__main__":
|
|
549
|
-
main()
|
|
524
|
+
main()
|
webscout/conversation.py
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
conversation.py
|
|
3
|
+
|
|
4
|
+
This module provides a modern conversation manager for handling chat-based interactions, message history, tool calls, and robust error handling. It defines the Conversation class and supporting types for managing conversational state, tool integration, and message validation.
|
|
5
|
+
|
|
6
|
+
Classes:
|
|
7
|
+
ConversationError: Base exception for conversation-related errors.
|
|
8
|
+
ToolCallError: Raised when there's an error with tool calls.
|
|
9
|
+
MessageValidationError: Raised when message validation fails.
|
|
10
|
+
Message: Represents a single message in the conversation.
|
|
11
|
+
FunctionCall: TypedDict for a function call.
|
|
12
|
+
ToolDefinition: TypedDict for a tool definition.
|
|
13
|
+
FunctionCallData: TypedDict for function call data.
|
|
14
|
+
Fn: Represents a function (tool) that the agent can call.
|
|
15
|
+
Conversation: Main conversation manager class.
|
|
16
|
+
|
|
17
|
+
Functions:
|
|
18
|
+
tools: Decorator to mark a function as a tool.
|
|
19
|
+
"""
|
|
1
20
|
import os
|
|
2
21
|
import json
|
|
3
|
-
import logging
|
|
4
22
|
from typing import Optional, Dict, List, Any, TypedDict, Callable, TypeVar, Union
|
|
5
23
|
from dataclasses import dataclass
|
|
6
24
|
from datetime import datetime
|
|
@@ -59,14 +77,15 @@ def tools(func: Callable[..., T]) -> Callable[..., T]:
|
|
|
59
77
|
return func
|
|
60
78
|
|
|
61
79
|
class Conversation:
|
|
62
|
-
"""
|
|
63
|
-
|
|
80
|
+
"""
|
|
81
|
+
Modern conversation manager with enhanced features.
|
|
82
|
+
|
|
64
83
|
Key Features:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
84
|
+
- Robust message handling with metadata
|
|
85
|
+
- Enhanced tool calling support
|
|
86
|
+
- Efficient history management
|
|
87
|
+
- Improved error handling
|
|
88
|
+
- Memory optimization
|
|
70
89
|
"""
|
|
71
90
|
|
|
72
91
|
intro = (
|
|
@@ -95,23 +114,8 @@ class Conversation:
|
|
|
95
114
|
self.prompt_allowance = 10
|
|
96
115
|
self.tools = tools or []
|
|
97
116
|
self.compression_threshold = compression_threshold
|
|
98
|
-
self.logger = self._setup_logger()
|
|
99
|
-
|
|
100
117
|
if filepath:
|
|
101
|
-
self.load_conversation(filepath,
|
|
102
|
-
|
|
103
|
-
def _setup_logger(self) -> logging.Logger:
|
|
104
|
-
"""Set up enhanced logging."""
|
|
105
|
-
logger = logging.getLogger("conversation")
|
|
106
|
-
if not logger.handlers:
|
|
107
|
-
handler = logging.StreamHandler()
|
|
108
|
-
formatter = logging.Formatter(
|
|
109
|
-
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
110
|
-
)
|
|
111
|
-
handler.setFormatter(formatter)
|
|
112
|
-
logger.addHandler(handler)
|
|
113
|
-
logger.setLevel(logging.INFO)
|
|
114
|
-
return logger
|
|
118
|
+
self.load_conversation(filepath, True)
|
|
115
119
|
|
|
116
120
|
def load_conversation(self, filepath: str, exists: bool = True) -> None:
|
|
117
121
|
"""Load conversation with improved error handling."""
|
|
@@ -132,7 +136,6 @@ class Conversation:
|
|
|
132
136
|
self.intro = file_contents[0]
|
|
133
137
|
self._process_history_from_file(file_contents[1:])
|
|
134
138
|
except Exception as e:
|
|
135
|
-
self.logger.error(f"Error loading conversation: {str(e)}")
|
|
136
139
|
raise ConversationError(f"Failed to load conversation: {str(e)}") from e
|
|
137
140
|
|
|
138
141
|
def _process_history_from_file(self, lines: List[str]) -> None:
|
|
@@ -272,6 +275,7 @@ Your goal is to assist the user effectively. Analyze each query and choose one o
|
|
|
272
275
|
def add_message(self, role: str, content: str, metadata: Optional[Dict[str, Any]] = None) -> None:
|
|
273
276
|
"""Add a message with enhanced validation and metadata support."""
|
|
274
277
|
try:
|
|
278
|
+
role = role.lower() # Normalize role to lowercase
|
|
275
279
|
if not self.validate_message(role, content):
|
|
276
280
|
raise MessageValidationError("Invalid message role or content")
|
|
277
281
|
|
|
@@ -284,7 +288,6 @@ Your goal is to assist the user effectively. Analyze each query and choose one o
|
|
|
284
288
|
self._compress_history()
|
|
285
289
|
|
|
286
290
|
except Exception as e:
|
|
287
|
-
self.logger.error(f"Error adding message: {str(e)}")
|
|
288
291
|
raise ConversationError(f"Failed to add message: {str(e)}") from e
|
|
289
292
|
|
|
290
293
|
def _append_to_file(self, message: Message) -> None:
|
|
@@ -299,17 +302,17 @@ Your goal is to assist the user effectively. Analyze each query and choose one o
|
|
|
299
302
|
fh.write(f"\n{role_display}: {message.content}")
|
|
300
303
|
|
|
301
304
|
except Exception as e:
|
|
302
|
-
self.logger.error(f"Error writing to file: {str(e)}")
|
|
303
305
|
raise ConversationError(f"Failed to write to file: {str(e)}") from e
|
|
304
306
|
|
|
305
307
|
def validate_message(self, role: str, content: str) -> bool:
|
|
306
308
|
"""Validate message with enhanced role checking."""
|
|
307
309
|
valid_roles = {'user', 'assistant', 'tool', 'system'}
|
|
308
310
|
if role not in valid_roles:
|
|
309
|
-
self.logger.error(f"Invalid role: {role}")
|
|
310
311
|
return False
|
|
311
|
-
if not
|
|
312
|
-
|
|
312
|
+
if not isinstance(content, str):
|
|
313
|
+
return False
|
|
314
|
+
# Allow empty content for assistant (needed for streaming)
|
|
315
|
+
if not content and role != 'assistant':
|
|
313
316
|
return False
|
|
314
317
|
return True
|
|
315
318
|
|
|
@@ -345,7 +348,6 @@ Your goal is to assist the user effectively. Analyze each query and choose one o
|
|
|
345
348
|
}
|
|
346
349
|
|
|
347
350
|
except Exception as e:
|
|
348
|
-
self.logger.error(f"Error handling tool response: {str(e)}")
|
|
349
351
|
raise ToolCallError(f"Failed to handle tool response: {str(e)}") from e
|
|
350
352
|
|
|
351
353
|
def _parse_function_call(self, response: str) -> FunctionCallData:
|
|
@@ -381,7 +383,6 @@ Your goal is to assist the user effectively. Analyze each query and choose one o
|
|
|
381
383
|
raise
|
|
382
384
|
|
|
383
385
|
except Exception as e:
|
|
384
|
-
self.logger.error(f"Error parsing function call: {str(e)}")
|
|
385
386
|
return {"error": str(e)}
|
|
386
387
|
|
|
387
388
|
def execute_function(self, function_call_data: FunctionCallData) -> str:
|
|
@@ -405,7 +406,6 @@ Your goal is to assist the user effectively. Analyze each query and choose one o
|
|
|
405
406
|
return "; ".join(results)
|
|
406
407
|
|
|
407
408
|
except Exception as e:
|
|
408
|
-
self.logger.error(f"Error executing function: {str(e)}")
|
|
409
409
|
raise ToolCallError(f"Failed to execute function: {str(e)}") from e
|
|
410
410
|
|
|
411
411
|
def get_tools_description(self) -> str:
|
|
@@ -428,9 +428,9 @@ Your goal is to assist the user effectively. Analyze each query and choose one o
|
|
|
428
428
|
This method adds both the user's prompt and the assistant's response
|
|
429
429
|
to the conversation history as separate messages.
|
|
430
430
|
"""
|
|
431
|
-
# Add user's message
|
|
431
|
+
# Add user's message (normalize role)
|
|
432
432
|
self.add_message("user", prompt)
|
|
433
433
|
|
|
434
|
-
# Add assistant's response
|
|
434
|
+
# Add assistant's response (normalize role)
|
|
435
435
|
self.add_message("assistant", response)
|
|
436
436
|
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# ๐ฅ LitAgent - The Lit User Agent Generator
|
|
2
|
+
|
|
3
|
+
LitAgent is a powerful and modern user agent generator that keeps your requests fresh and undetectable! Built with style and packed with features, it's your go-to solution for managing user agents in your web scraping projects.
|
|
4
|
+
|
|
5
|
+
## ๐ Quick Start
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from webscout import LitAgent
|
|
9
|
+
|
|
10
|
+
# Create a LitAgent instance
|
|
11
|
+
agent = LitAgent()
|
|
12
|
+
|
|
13
|
+
# Get a random user agent
|
|
14
|
+
ua = agent.random()
|
|
15
|
+
print(ua) # Mozilla/5.0 (Windows NT 11.0) AppleWebKit/537.36 ...
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## ๐ฏ Features
|
|
19
|
+
|
|
20
|
+
### Browser-Specific Agents
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
# Get agents for specific browsers
|
|
24
|
+
chrome_ua = agent.chrome() # Latest Chrome agent
|
|
25
|
+
firefox_ua = agent.firefox() # Latest Firefox agent
|
|
26
|
+
safari_ua = agent.safari() # Latest Safari agent
|
|
27
|
+
edge_ua = agent.edge() # Latest Edge agent
|
|
28
|
+
opera_ua = agent.opera() # Latest Opera agent
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Device-Specific Agents
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
# Get mobile or desktop agents
|
|
35
|
+
mobile_ua = agent.mobile() # Mobile device agent
|
|
36
|
+
desktop_ua = agent.desktop() # Desktop device agent
|
|
37
|
+
|
|
38
|
+
# New - Get agents for specific device types
|
|
39
|
+
tablet_ua = agent.tablet() # Tablet device agent
|
|
40
|
+
tv_ua = agent.smart_tv() # Smart TV agent
|
|
41
|
+
console_ua = agent.gaming() # Gaming console agent
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### OS-Specific Agents
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
# New - Get agents for specific operating systems
|
|
48
|
+
windows_ua = agent.windows() # Windows agent
|
|
49
|
+
mac_ua = agent.macos() # macOS agent
|
|
50
|
+
linux_ua = agent.linux() # Linux agent
|
|
51
|
+
android_ua = agent.android() # Android agent
|
|
52
|
+
ios_ua = agent.ios() # iOS agent
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Custom Agent Generation
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
# New - Generate custom user agents with specific attributes
|
|
59
|
+
custom_ua = agent.custom(
|
|
60
|
+
browser="chrome",
|
|
61
|
+
version="91.0",
|
|
62
|
+
os="windows",
|
|
63
|
+
os_version="10",
|
|
64
|
+
device_type="desktop"
|
|
65
|
+
)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Keep It Fresh
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
# Refresh your agents pool anytime
|
|
72
|
+
agent.refresh() # Generates new set of agents
|
|
73
|
+
|
|
74
|
+
# New - Schedule automatic refreshes
|
|
75
|
+
agent.auto_refresh(interval_minutes=30) # Auto-refresh every 30 minutes
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## ๐ซ Real-World Examples
|
|
79
|
+
|
|
80
|
+
### With Requests
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
import requests
|
|
84
|
+
from webscout import LitAgent
|
|
85
|
+
|
|
86
|
+
agent = LitAgent()
|
|
87
|
+
|
|
88
|
+
def make_request(url):
|
|
89
|
+
headers = {
|
|
90
|
+
'User-Agent': agent.random(),
|
|
91
|
+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
92
|
+
'Accept-Language': 'en-US,en;q=0.5',
|
|
93
|
+
'Connection': 'keep-alive',
|
|
94
|
+
}
|
|
95
|
+
return requests.get(url, headers=headers)
|
|
96
|
+
|
|
97
|
+
# Make requests with different agents
|
|
98
|
+
response1 = make_request('https://api.example.com') # Random agent
|
|
99
|
+
response2 = make_request('https://mobile.example.com') # Another random agent
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### With aiohttp
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
import aiohttp
|
|
106
|
+
import asyncio
|
|
107
|
+
from webscout import LitAgent
|
|
108
|
+
|
|
109
|
+
agent = LitAgent()
|
|
110
|
+
|
|
111
|
+
async def fetch(url):
|
|
112
|
+
headers = {'User-Agent': agent.random()}
|
|
113
|
+
async with aiohttp.ClientSession() as session:
|
|
114
|
+
async with session.get(url, headers=headers) as response:
|
|
115
|
+
return await response.text()
|
|
116
|
+
|
|
117
|
+
# Use it in your async code
|
|
118
|
+
async def main():
|
|
119
|
+
urls = [
|
|
120
|
+
'https://api1.example.com',
|
|
121
|
+
'https://api2.example.com',
|
|
122
|
+
'https://api3.example.com'
|
|
123
|
+
]
|
|
124
|
+
tasks = [fetch(url) for url in urls]
|
|
125
|
+
results = await asyncio.gather(*tasks)
|
|
126
|
+
return results
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### With Selenium
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from selenium import webdriver
|
|
133
|
+
from webscout import LitAgent
|
|
134
|
+
|
|
135
|
+
agent = LitAgent()
|
|
136
|
+
|
|
137
|
+
def create_driver():
|
|
138
|
+
options = webdriver.ChromeOptions()
|
|
139
|
+
options.add_argument(f'user-agent={agent.chrome()}')
|
|
140
|
+
return webdriver.Chrome(options=options)
|
|
141
|
+
|
|
142
|
+
# Use it with Selenium
|
|
143
|
+
driver = create_driver()
|
|
144
|
+
driver.get('https://example.com')
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### New - With Playwright
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from playwright.sync_api import sync_playwright
|
|
151
|
+
from webscout import LitAgent
|
|
152
|
+
|
|
153
|
+
agent = LitAgent()
|
|
154
|
+
|
|
155
|
+
def browse_with_playwright():
|
|
156
|
+
with sync_playwright() as p:
|
|
157
|
+
browser_options = {
|
|
158
|
+
"user_agent": agent.chrome(),
|
|
159
|
+
"viewport": {"width": 1280, "height": 720}
|
|
160
|
+
}
|
|
161
|
+
browser = p.chromium.launch()
|
|
162
|
+
context = browser.new_context(**browser_options)
|
|
163
|
+
page = context.new_page()
|
|
164
|
+
page.goto('https://example.com')
|
|
165
|
+
# Continue with your scraping logic
|
|
166
|
+
browser.close()
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## ๐ Pro Tips
|
|
170
|
+
|
|
171
|
+
1. **Rotate Agents**: Refresh your agents pool periodically to avoid detection
|
|
172
|
+
```python
|
|
173
|
+
agent = LitAgent()
|
|
174
|
+
for _ in range(10):
|
|
175
|
+
response = requests.get(url, headers={'User-Agent': agent.random()})
|
|
176
|
+
if _ % 3 == 0: # Refresh every 3 requests
|
|
177
|
+
agent.refresh()
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
2. **Device-Specific Scraping**: Use appropriate agents for different platforms
|
|
181
|
+
```python
|
|
182
|
+
# Mobile site scraping
|
|
183
|
+
mobile_response = requests.get(
|
|
184
|
+
'https://m.example.com',
|
|
185
|
+
headers={'User-Agent': agent.mobile()}
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# Desktop site scraping
|
|
189
|
+
desktop_response = requests.get(
|
|
190
|
+
'https://example.com',
|
|
191
|
+
headers={'User-Agent': agent.desktop()}
|
|
192
|
+
)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
3. **Browser Consistency**: Stick to one browser type per session
|
|
196
|
+
```python
|
|
197
|
+
chrome_agent = agent.chrome()
|
|
198
|
+
headers = {
|
|
199
|
+
'User-Agent': chrome_agent,
|
|
200
|
+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
|
|
201
|
+
}
|
|
202
|
+
# Use these headers for all requests in this session
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
4. **New - Browser Fingerprinting Defense**:
|
|
206
|
+
```python
|
|
207
|
+
# Create consistent browser fingerprinting
|
|
208
|
+
fingerprint = agent.generate_fingerprint(browser="chrome")
|
|
209
|
+
|
|
210
|
+
headers = {
|
|
211
|
+
'User-Agent': fingerprint['user_agent'],
|
|
212
|
+
'Accept-Language': fingerprint['accept_language'],
|
|
213
|
+
'Accept': fingerprint['accept'],
|
|
214
|
+
'Sec-Ch-Ua': fingerprint['sec_ch_ua'],
|
|
215
|
+
'Sec-Ch-Ua-Platform': fingerprint['platform']
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
# Use this consistent set for all session requests
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
5. **New - Multi-threading Support**:
|
|
222
|
+
```python
|
|
223
|
+
import concurrent.futures
|
|
224
|
+
from webscout import LitAgent
|
|
225
|
+
|
|
226
|
+
agent = LitAgent(thread_safe=True) # Thread-safe instance
|
|
227
|
+
|
|
228
|
+
def fetch_url(url):
|
|
229
|
+
headers = {'User-Agent': agent.random()}
|
|
230
|
+
return requests.get(url, headers=headers).text
|
|
231
|
+
|
|
232
|
+
urls = ['https://example1.com', 'https://example2.com', 'https://example3.com']
|
|
233
|
+
|
|
234
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
|
|
235
|
+
results = list(executor.map(fetch_url, urls))
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## ๐ง Supported Browsers & Devices
|
|
239
|
+
|
|
240
|
+
- **Browsers**: Chrome, Firefox, Safari, Edge, Opera, Brave, Vivaldi
|
|
241
|
+
- **Operating Systems**: Windows, macOS, Linux, Android, iOS, Chrome OS
|
|
242
|
+
- **Devices**: Mobile phones, Tablets, Desktops, Game consoles, Smart TVs, Wearables
|
|
243
|
+
|
|
244
|
+
## ๐จ Why LitAgent?
|
|
245
|
+
|
|
246
|
+
- ๐ Modern and up-to-date user agents
|
|
247
|
+
- ๐ช Easy to use, hard to detect
|
|
248
|
+
- ๐ Fresh agents on demand
|
|
249
|
+
- ๐ฑ Device-specific agents
|
|
250
|
+
- ๐ All major browsers supported
|
|
251
|
+
- โก Lightweight and fast
|
|
252
|
+
- ๐งฉ Advanced fingerprinting protection
|
|
253
|
+
- ๐ Seamless proxy integration
|
|
254
|
+
- ๐งต Thread-safe operation
|
|
255
|
+
- ๐ฐ๏ธ Automatic refresh scheduling
|
|
256
|
+
|
|
257
|
+
## ๐ New - Analytics and Reporting
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
# Get statistics on your agent usage
|
|
261
|
+
stats = agent.get_stats()
|
|
262
|
+
print(f"Agents generated: {stats.total_generated}")
|
|
263
|
+
print(f"Most used browser: {stats.top_browser}")
|
|
264
|
+
print(f"Detection avoidance rate: {stats.avoidance_rate}%")
|
|
265
|
+
|
|
266
|
+
# Export your usage data
|
|
267
|
+
agent.export_stats('agent_usage.json')
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## ๐ Installation
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
pip install webscout
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Made with ๐ by the HelpingAI team
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LitAgent - A lit user agent generator with infinite possibilities! ๐ฅ
|
|
3
|
+
|
|
4
|
+
Examples:
|
|
5
|
+
>>> from webscout import LitAgent
|
|
6
|
+
>>> agent = LitAgent()
|
|
7
|
+
>>>
|
|
8
|
+
>>> # Get random user agents
|
|
9
|
+
>>> agent.random() # Random agent from any browser
|
|
10
|
+
>>> agent.mobile() # Random mobile device agent
|
|
11
|
+
>>> agent.desktop() # Random desktop agent
|
|
12
|
+
>>>
|
|
13
|
+
>>> # Browser specific agents
|
|
14
|
+
>>> agent.chrome() # Latest Chrome browser
|
|
15
|
+
>>> agent.firefox() # Latest Firefox browser
|
|
16
|
+
>>> agent.safari() # Latest Safari browser
|
|
17
|
+
>>> agent.edge() # Latest Edge browser
|
|
18
|
+
>>> agent.opera() # Latest Opera browser
|
|
19
|
+
>>>
|
|
20
|
+
>>> # Refresh your agents
|
|
21
|
+
>>> agent.refresh() # Get fresh new agents
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from .agent import LitAgent
|
|
25
|
+
from .constants import BROWSERS, OS_VERSIONS, DEVICES, FINGERPRINTS
|
|
26
|
+
|
|
27
|
+
agent = LitAgent()
|
|
28
|
+
|
|
29
|
+
__all__ = ['LitAgent', 'agent', 'BROWSERS', 'OS_VERSIONS', 'DEVICES', 'FINGERPRINTS']
|