webscout 8.2.2__py3-none-any.whl → 2026.1.19__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.
- webscout/AIauto.py +524 -143
- webscout/AIbase.py +247 -123
- webscout/AIutel.py +68 -132
- webscout/Bard.py +1072 -535
- webscout/Extra/GitToolkit/__init__.py +2 -2
- webscout/Extra/GitToolkit/gitapi/__init__.py +20 -12
- webscout/Extra/GitToolkit/gitapi/gist.py +142 -0
- webscout/Extra/GitToolkit/gitapi/organization.py +91 -0
- webscout/Extra/GitToolkit/gitapi/repository.py +308 -195
- webscout/Extra/GitToolkit/gitapi/search.py +162 -0
- webscout/Extra/GitToolkit/gitapi/trending.py +236 -0
- webscout/Extra/GitToolkit/gitapi/user.py +128 -96
- webscout/Extra/GitToolkit/gitapi/utils.py +82 -62
- webscout/Extra/YTToolkit/README.md +443 -0
- webscout/Extra/YTToolkit/YTdownloader.py +953 -957
- webscout/Extra/YTToolkit/__init__.py +3 -3
- webscout/Extra/YTToolkit/transcriber.py +595 -476
- webscout/Extra/YTToolkit/ytapi/README.md +230 -0
- webscout/Extra/YTToolkit/ytapi/__init__.py +22 -6
- webscout/Extra/YTToolkit/ytapi/captions.py +190 -0
- webscout/Extra/YTToolkit/ytapi/channel.py +302 -307
- webscout/Extra/YTToolkit/ytapi/errors.py +13 -13
- webscout/Extra/YTToolkit/ytapi/extras.py +178 -45
- webscout/Extra/YTToolkit/ytapi/hashtag.py +120 -0
- webscout/Extra/YTToolkit/ytapi/https.py +89 -88
- webscout/Extra/YTToolkit/ytapi/patterns.py +61 -61
- webscout/Extra/YTToolkit/ytapi/playlist.py +59 -59
- webscout/Extra/YTToolkit/ytapi/pool.py +8 -8
- webscout/Extra/YTToolkit/ytapi/query.py +143 -40
- webscout/Extra/YTToolkit/ytapi/shorts.py +122 -0
- webscout/Extra/YTToolkit/ytapi/stream.py +68 -63
- webscout/Extra/YTToolkit/ytapi/suggestions.py +97 -0
- webscout/Extra/YTToolkit/ytapi/utils.py +66 -62
- webscout/Extra/YTToolkit/ytapi/video.py +189 -18
- webscout/Extra/__init__.py +2 -3
- webscout/Extra/gguf.py +1298 -682
- webscout/Extra/tempmail/README.md +488 -0
- webscout/Extra/tempmail/__init__.py +28 -28
- webscout/Extra/tempmail/async_utils.py +143 -141
- webscout/Extra/tempmail/base.py +172 -161
- webscout/Extra/tempmail/cli.py +191 -187
- webscout/Extra/tempmail/emailnator.py +88 -84
- webscout/Extra/tempmail/mail_tm.py +378 -361
- webscout/Extra/tempmail/temp_mail_io.py +304 -292
- webscout/Extra/weather.py +196 -194
- webscout/Extra/weather_ascii.py +17 -15
- webscout/Provider/AISEARCH/PERPLEXED_search.py +175 -0
- webscout/Provider/AISEARCH/Perplexity.py +237 -304
- webscout/Provider/AISEARCH/README.md +106 -0
- webscout/Provider/AISEARCH/__init__.py +16 -10
- webscout/Provider/AISEARCH/brave_search.py +298 -0
- webscout/Provider/AISEARCH/iask_search.py +130 -209
- webscout/Provider/AISEARCH/monica_search.py +200 -246
- webscout/Provider/AISEARCH/webpilotai_search.py +242 -281
- webscout/Provider/Algion.py +413 -0
- webscout/Provider/Andi.py +74 -69
- webscout/Provider/Apriel.py +313 -0
- webscout/Provider/Ayle.py +323 -0
- webscout/Provider/ChatSandbox.py +329 -0
- webscout/Provider/ClaudeOnline.py +365 -0
- webscout/Provider/Cohere.py +232 -208
- webscout/Provider/DeepAI.py +367 -0
- webscout/Provider/Deepinfra.py +343 -173
- webscout/Provider/EssentialAI.py +217 -0
- webscout/Provider/ExaAI.py +274 -261
- webscout/Provider/Gemini.py +60 -54
- webscout/Provider/GithubChat.py +385 -367
- webscout/Provider/Gradient.py +286 -0
- webscout/Provider/Groq.py +556 -670
- webscout/Provider/HadadXYZ.py +323 -0
- webscout/Provider/HeckAI.py +392 -233
- webscout/Provider/HuggingFace.py +387 -0
- webscout/Provider/IBM.py +340 -0
- webscout/Provider/Jadve.py +317 -266
- webscout/Provider/K2Think.py +306 -0
- webscout/Provider/Koboldai.py +221 -381
- webscout/Provider/Netwrck.py +273 -228
- webscout/Provider/Nvidia.py +310 -0
- webscout/Provider/OPENAI/DeepAI.py +489 -0
- webscout/Provider/OPENAI/K2Think.py +423 -0
- webscout/Provider/OPENAI/PI.py +463 -0
- webscout/Provider/OPENAI/README.md +890 -0
- webscout/Provider/OPENAI/TogetherAI.py +405 -0
- webscout/Provider/OPENAI/TwoAI.py +255 -0
- webscout/Provider/OPENAI/__init__.py +148 -25
- webscout/Provider/OPENAI/ai4chat.py +348 -0
- webscout/Provider/OPENAI/akashgpt.py +436 -0
- webscout/Provider/OPENAI/algion.py +303 -0
- webscout/Provider/OPENAI/ayle.py +365 -0
- webscout/Provider/OPENAI/base.py +253 -46
- webscout/Provider/OPENAI/cerebras.py +296 -0
- webscout/Provider/OPENAI/chatgpt.py +514 -193
- webscout/Provider/OPENAI/chatsandbox.py +233 -0
- webscout/Provider/OPENAI/deepinfra.py +403 -272
- webscout/Provider/OPENAI/e2b.py +2370 -1350
- webscout/Provider/OPENAI/elmo.py +278 -0
- webscout/Provider/OPENAI/exaai.py +186 -138
- webscout/Provider/OPENAI/freeassist.py +446 -0
- webscout/Provider/OPENAI/gradient.py +448 -0
- webscout/Provider/OPENAI/groq.py +380 -0
- webscout/Provider/OPENAI/hadadxyz.py +292 -0
- webscout/Provider/OPENAI/heckai.py +100 -104
- webscout/Provider/OPENAI/huggingface.py +321 -0
- webscout/Provider/OPENAI/ibm.py +425 -0
- webscout/Provider/OPENAI/llmchat.py +253 -0
- webscout/Provider/OPENAI/llmchatco.py +378 -327
- webscout/Provider/OPENAI/meta.py +541 -0
- webscout/Provider/OPENAI/netwrck.py +110 -84
- webscout/Provider/OPENAI/nvidia.py +317 -0
- webscout/Provider/OPENAI/oivscode.py +348 -0
- webscout/Provider/OPENAI/openrouter.py +328 -0
- webscout/Provider/OPENAI/pydantic_imports.py +1 -0
- webscout/Provider/OPENAI/sambanova.py +397 -0
- webscout/Provider/OPENAI/sonus.py +126 -115
- webscout/Provider/OPENAI/textpollinations.py +218 -133
- webscout/Provider/OPENAI/toolbaz.py +136 -166
- webscout/Provider/OPENAI/typefully.py +419 -0
- webscout/Provider/OPENAI/typliai.py +279 -0
- webscout/Provider/OPENAI/utils.py +314 -211
- webscout/Provider/OPENAI/wisecat.py +103 -125
- webscout/Provider/OPENAI/writecream.py +185 -156
- webscout/Provider/OPENAI/x0gpt.py +227 -136
- webscout/Provider/OPENAI/zenmux.py +380 -0
- webscout/Provider/OpenRouter.py +386 -0
- webscout/Provider/Openai.py +337 -496
- webscout/Provider/PI.py +443 -344
- webscout/Provider/QwenLM.py +346 -254
- webscout/Provider/STT/__init__.py +28 -0
- webscout/Provider/STT/base.py +303 -0
- webscout/Provider/STT/elevenlabs.py +264 -0
- webscout/Provider/Sambanova.py +317 -0
- webscout/Provider/TTI/README.md +69 -0
- webscout/Provider/TTI/__init__.py +37 -12
- webscout/Provider/TTI/base.py +147 -0
- webscout/Provider/TTI/claudeonline.py +393 -0
- webscout/Provider/TTI/magicstudio.py +292 -0
- webscout/Provider/TTI/miragic.py +180 -0
- webscout/Provider/TTI/pollinations.py +331 -0
- webscout/Provider/TTI/together.py +334 -0
- webscout/Provider/TTI/utils.py +14 -0
- webscout/Provider/TTS/README.md +186 -0
- webscout/Provider/TTS/__init__.py +43 -7
- webscout/Provider/TTS/base.py +523 -0
- webscout/Provider/TTS/deepgram.py +286 -156
- webscout/Provider/TTS/elevenlabs.py +189 -111
- webscout/Provider/TTS/freetts.py +218 -0
- webscout/Provider/TTS/murfai.py +288 -113
- webscout/Provider/TTS/openai_fm.py +364 -0
- webscout/Provider/TTS/parler.py +203 -111
- webscout/Provider/TTS/qwen.py +334 -0
- webscout/Provider/TTS/sherpa.py +286 -0
- webscout/Provider/TTS/speechma.py +693 -180
- webscout/Provider/TTS/streamElements.py +275 -333
- webscout/Provider/TTS/utils.py +280 -280
- webscout/Provider/TextPollinationsAI.py +221 -121
- webscout/Provider/TogetherAI.py +450 -0
- webscout/Provider/TwoAI.py +309 -199
- webscout/Provider/TypliAI.py +311 -0
- webscout/Provider/UNFINISHED/ChatHub.py +219 -0
- webscout/Provider/{OPENAI/glider.py → UNFINISHED/ChutesAI.py} +160 -145
- webscout/Provider/UNFINISHED/GizAI.py +300 -0
- webscout/Provider/UNFINISHED/Marcus.py +218 -0
- webscout/Provider/UNFINISHED/Qodo.py +481 -0
- webscout/Provider/UNFINISHED/XenAI.py +330 -0
- webscout/Provider/{Youchat.py → UNFINISHED/Youchat.py} +64 -47
- webscout/Provider/UNFINISHED/aihumanizer.py +41 -0
- webscout/Provider/UNFINISHED/grammerchecker.py +37 -0
- webscout/Provider/UNFINISHED/liner.py +342 -0
- webscout/Provider/UNFINISHED/liner_api_request.py +246 -0
- webscout/Provider/UNFINISHED/samurai.py +231 -0
- webscout/Provider/WiseCat.py +256 -196
- webscout/Provider/WrDoChat.py +390 -0
- webscout/Provider/__init__.py +115 -198
- webscout/Provider/ai4chat.py +181 -202
- webscout/Provider/akashgpt.py +330 -342
- webscout/Provider/cerebras.py +397 -242
- webscout/Provider/cleeai.py +236 -213
- webscout/Provider/elmo.py +291 -234
- webscout/Provider/geminiapi.py +343 -208
- webscout/Provider/julius.py +245 -223
- webscout/Provider/learnfastai.py +333 -266
- webscout/Provider/llama3mitril.py +230 -180
- webscout/Provider/llmchat.py +308 -213
- webscout/Provider/llmchatco.py +321 -311
- webscout/Provider/meta.py +996 -794
- webscout/Provider/oivscode.py +332 -0
- webscout/Provider/searchchat.py +316 -293
- webscout/Provider/sonus.py +264 -208
- webscout/Provider/toolbaz.py +359 -320
- webscout/Provider/turboseek.py +332 -219
- webscout/Provider/typefully.py +262 -280
- webscout/Provider/x0gpt.py +332 -256
- webscout/__init__.py +31 -38
- webscout/__main__.py +5 -5
- webscout/cli.py +585 -293
- webscout/client.py +1497 -0
- webscout/conversation.py +140 -565
- webscout/exceptions.py +383 -339
- webscout/litagent/__init__.py +29 -29
- webscout/litagent/agent.py +492 -455
- webscout/litagent/constants.py +60 -60
- webscout/models.py +505 -181
- webscout/optimizers.py +32 -378
- webscout/prompt_manager.py +376 -274
- webscout/sanitize.py +1514 -0
- webscout/scout/README.md +452 -0
- webscout/scout/__init__.py +8 -8
- webscout/scout/core/__init__.py +7 -7
- webscout/scout/core/crawler.py +330 -140
- webscout/scout/core/scout.py +800 -568
- webscout/scout/core/search_result.py +51 -96
- webscout/scout/core/text_analyzer.py +64 -63
- webscout/scout/core/text_utils.py +412 -277
- webscout/scout/core/web_analyzer.py +54 -52
- webscout/scout/element.py +872 -460
- webscout/scout/parsers/__init__.py +70 -69
- webscout/scout/parsers/html5lib_parser.py +182 -172
- webscout/scout/parsers/html_parser.py +238 -236
- webscout/scout/parsers/lxml_parser.py +203 -178
- webscout/scout/utils.py +38 -37
- webscout/search/__init__.py +47 -0
- webscout/search/base.py +201 -0
- webscout/search/bing_main.py +45 -0
- webscout/search/brave_main.py +92 -0
- webscout/search/duckduckgo_main.py +57 -0
- webscout/search/engines/__init__.py +127 -0
- webscout/search/engines/bing/__init__.py +15 -0
- webscout/search/engines/bing/base.py +35 -0
- webscout/search/engines/bing/images.py +114 -0
- webscout/search/engines/bing/news.py +96 -0
- webscout/search/engines/bing/suggestions.py +36 -0
- webscout/search/engines/bing/text.py +109 -0
- webscout/search/engines/brave/__init__.py +19 -0
- webscout/search/engines/brave/base.py +47 -0
- webscout/search/engines/brave/images.py +213 -0
- webscout/search/engines/brave/news.py +353 -0
- webscout/search/engines/brave/suggestions.py +318 -0
- webscout/search/engines/brave/text.py +167 -0
- webscout/search/engines/brave/videos.py +364 -0
- webscout/search/engines/duckduckgo/__init__.py +25 -0
- webscout/search/engines/duckduckgo/answers.py +80 -0
- webscout/search/engines/duckduckgo/base.py +189 -0
- webscout/search/engines/duckduckgo/images.py +100 -0
- webscout/search/engines/duckduckgo/maps.py +183 -0
- webscout/search/engines/duckduckgo/news.py +70 -0
- webscout/search/engines/duckduckgo/suggestions.py +22 -0
- webscout/search/engines/duckduckgo/text.py +221 -0
- webscout/search/engines/duckduckgo/translate.py +48 -0
- webscout/search/engines/duckduckgo/videos.py +80 -0
- webscout/search/engines/duckduckgo/weather.py +84 -0
- webscout/search/engines/mojeek.py +61 -0
- webscout/search/engines/wikipedia.py +77 -0
- webscout/search/engines/yahoo/__init__.py +41 -0
- webscout/search/engines/yahoo/answers.py +19 -0
- webscout/search/engines/yahoo/base.py +34 -0
- webscout/search/engines/yahoo/images.py +323 -0
- webscout/search/engines/yahoo/maps.py +19 -0
- webscout/search/engines/yahoo/news.py +258 -0
- webscout/search/engines/yahoo/suggestions.py +140 -0
- webscout/search/engines/yahoo/text.py +273 -0
- webscout/search/engines/yahoo/translate.py +19 -0
- webscout/search/engines/yahoo/videos.py +302 -0
- webscout/search/engines/yahoo/weather.py +220 -0
- webscout/search/engines/yandex.py +67 -0
- webscout/search/engines/yep/__init__.py +13 -0
- webscout/search/engines/yep/base.py +34 -0
- webscout/search/engines/yep/images.py +101 -0
- webscout/search/engines/yep/suggestions.py +38 -0
- webscout/search/engines/yep/text.py +99 -0
- webscout/search/http_client.py +172 -0
- webscout/search/results.py +141 -0
- webscout/search/yahoo_main.py +57 -0
- webscout/search/yep_main.py +48 -0
- webscout/server/__init__.py +48 -0
- webscout/server/config.py +78 -0
- webscout/server/exceptions.py +69 -0
- webscout/server/providers.py +286 -0
- webscout/server/request_models.py +131 -0
- webscout/server/request_processing.py +404 -0
- webscout/server/routes.py +642 -0
- webscout/server/server.py +351 -0
- webscout/server/ui_templates.py +1171 -0
- webscout/swiftcli/__init__.py +79 -809
- webscout/swiftcli/core/__init__.py +7 -0
- webscout/swiftcli/core/cli.py +574 -0
- webscout/swiftcli/core/context.py +98 -0
- webscout/swiftcli/core/group.py +268 -0
- webscout/swiftcli/decorators/__init__.py +28 -0
- webscout/swiftcli/decorators/command.py +243 -0
- webscout/swiftcli/decorators/options.py +247 -0
- webscout/swiftcli/decorators/output.py +392 -0
- webscout/swiftcli/exceptions.py +21 -0
- webscout/swiftcli/plugins/__init__.py +9 -0
- webscout/swiftcli/plugins/base.py +134 -0
- webscout/swiftcli/plugins/manager.py +269 -0
- webscout/swiftcli/utils/__init__.py +58 -0
- webscout/swiftcli/utils/formatting.py +251 -0
- webscout/swiftcli/utils/parsing.py +368 -0
- webscout/update_checker.py +280 -136
- webscout/utils.py +28 -14
- webscout/version.py +2 -1
- webscout/version.py.bak +3 -0
- webscout/zeroart/__init__.py +218 -55
- webscout/zeroart/base.py +70 -60
- webscout/zeroart/effects.py +155 -99
- webscout/zeroart/fonts.py +1799 -816
- webscout-2026.1.19.dist-info/METADATA +638 -0
- webscout-2026.1.19.dist-info/RECORD +312 -0
- {webscout-8.2.2.dist-info → webscout-2026.1.19.dist-info}/WHEEL +1 -1
- webscout-2026.1.19.dist-info/entry_points.txt +4 -0
- webscout-2026.1.19.dist-info/top_level.txt +1 -0
- inferno/__init__.py +0 -6
- inferno/__main__.py +0 -9
- inferno/cli.py +0 -6
- webscout/DWEBS.py +0 -477
- webscout/Extra/autocoder/__init__.py +0 -9
- webscout/Extra/autocoder/autocoder.py +0 -849
- webscout/Extra/autocoder/autocoder_utiles.py +0 -332
- webscout/LLM.py +0 -442
- webscout/Litlogger/__init__.py +0 -67
- webscout/Litlogger/core/__init__.py +0 -6
- webscout/Litlogger/core/level.py +0 -23
- webscout/Litlogger/core/logger.py +0 -165
- webscout/Litlogger/handlers/__init__.py +0 -12
- webscout/Litlogger/handlers/console.py +0 -33
- webscout/Litlogger/handlers/file.py +0 -143
- webscout/Litlogger/handlers/network.py +0 -173
- webscout/Litlogger/styles/__init__.py +0 -7
- webscout/Litlogger/styles/colors.py +0 -249
- webscout/Litlogger/styles/formats.py +0 -458
- webscout/Litlogger/styles/text.py +0 -87
- webscout/Litlogger/utils/__init__.py +0 -6
- webscout/Litlogger/utils/detectors.py +0 -153
- webscout/Litlogger/utils/formatters.py +0 -200
- webscout/Local/__init__.py +0 -12
- webscout/Local/__main__.py +0 -9
- webscout/Local/api.py +0 -576
- webscout/Local/cli.py +0 -516
- webscout/Local/config.py +0 -75
- webscout/Local/llm.py +0 -287
- webscout/Local/model_manager.py +0 -253
- webscout/Local/server.py +0 -721
- webscout/Local/utils.py +0 -93
- webscout/Provider/AI21.py +0 -177
- webscout/Provider/AISEARCH/DeepFind.py +0 -250
- webscout/Provider/AISEARCH/ISou.py +0 -256
- webscout/Provider/AISEARCH/felo_search.py +0 -228
- webscout/Provider/AISEARCH/genspark_search.py +0 -208
- webscout/Provider/AISEARCH/hika_search.py +0 -194
- webscout/Provider/AISEARCH/scira_search.py +0 -324
- webscout/Provider/Aitopia.py +0 -292
- webscout/Provider/AllenAI.py +0 -413
- webscout/Provider/Blackboxai.py +0 -229
- webscout/Provider/C4ai.py +0 -432
- webscout/Provider/ChatGPTClone.py +0 -226
- webscout/Provider/ChatGPTES.py +0 -237
- webscout/Provider/ChatGPTGratis.py +0 -194
- webscout/Provider/Chatify.py +0 -175
- webscout/Provider/Cloudflare.py +0 -273
- webscout/Provider/DeepSeek.py +0 -196
- webscout/Provider/ElectronHub.py +0 -709
- webscout/Provider/ExaChat.py +0 -342
- webscout/Provider/Free2GPT.py +0 -241
- webscout/Provider/GPTWeb.py +0 -193
- webscout/Provider/Glider.py +0 -211
- webscout/Provider/HF_space/__init__.py +0 -0
- webscout/Provider/HF_space/qwen_qwen2.py +0 -206
- webscout/Provider/HuggingFaceChat.py +0 -462
- webscout/Provider/Hunyuan.py +0 -272
- webscout/Provider/LambdaChat.py +0 -392
- webscout/Provider/Llama.py +0 -200
- webscout/Provider/Llama3.py +0 -204
- webscout/Provider/Marcus.py +0 -148
- webscout/Provider/OLLAMA.py +0 -396
- webscout/Provider/OPENAI/c4ai.py +0 -367
- webscout/Provider/OPENAI/chatgptclone.py +0 -460
- webscout/Provider/OPENAI/exachat.py +0 -433
- webscout/Provider/OPENAI/freeaichat.py +0 -352
- webscout/Provider/OPENAI/opkfc.py +0 -488
- webscout/Provider/OPENAI/scirachat.py +0 -463
- webscout/Provider/OPENAI/standardinput.py +0 -425
- webscout/Provider/OPENAI/typegpt.py +0 -346
- webscout/Provider/OPENAI/uncovrAI.py +0 -455
- webscout/Provider/OPENAI/venice.py +0 -413
- webscout/Provider/OPENAI/yep.py +0 -327
- webscout/Provider/OpenGPT.py +0 -199
- webscout/Provider/Perplexitylabs.py +0 -415
- webscout/Provider/Phind.py +0 -535
- webscout/Provider/PizzaGPT.py +0 -198
- webscout/Provider/Reka.py +0 -214
- webscout/Provider/StandardInput.py +0 -278
- webscout/Provider/TTI/AiForce/__init__.py +0 -22
- webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
- webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
- webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
- webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
- webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
- webscout/Provider/TTI/ImgSys/__init__.py +0 -23
- webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
- webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
- webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
- webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
- webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
- webscout/Provider/TTI/Nexra/__init__.py +0 -22
- webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
- webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
- webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
- webscout/Provider/TTI/aiarta/__init__.py +0 -2
- webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
- webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
- webscout/Provider/TTI/artbit/__init__.py +0 -22
- webscout/Provider/TTI/artbit/async_artbit.py +0 -155
- webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
- webscout/Provider/TTI/fastflux/__init__.py +0 -22
- webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
- webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
- webscout/Provider/TTI/huggingface/__init__.py +0 -22
- webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
- webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
- webscout/Provider/TTI/piclumen/__init__.py +0 -23
- webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
- webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
- webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
- webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
- webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
- webscout/Provider/TTI/talkai/__init__.py +0 -4
- webscout/Provider/TTI/talkai/async_talkai.py +0 -229
- webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
- webscout/Provider/TTS/gesserit.py +0 -127
- webscout/Provider/TeachAnything.py +0 -187
- webscout/Provider/Venice.py +0 -219
- webscout/Provider/VercelAI.py +0 -234
- webscout/Provider/WebSim.py +0 -228
- webscout/Provider/Writecream.py +0 -211
- webscout/Provider/WritingMate.py +0 -197
- webscout/Provider/aimathgpt.py +0 -189
- webscout/Provider/askmyai.py +0 -158
- webscout/Provider/asksteve.py +0 -203
- webscout/Provider/bagoodex.py +0 -145
- webscout/Provider/chatglm.py +0 -205
- webscout/Provider/copilot.py +0 -428
- webscout/Provider/freeaichat.py +0 -271
- webscout/Provider/gaurish.py +0 -244
- webscout/Provider/geminiprorealtime.py +0 -160
- webscout/Provider/granite.py +0 -187
- webscout/Provider/hermes.py +0 -219
- webscout/Provider/koala.py +0 -268
- webscout/Provider/labyrinth.py +0 -340
- webscout/Provider/lepton.py +0 -194
- webscout/Provider/llamatutor.py +0 -192
- webscout/Provider/multichat.py +0 -325
- webscout/Provider/promptrefine.py +0 -193
- webscout/Provider/scira_chat.py +0 -277
- webscout/Provider/scnet.py +0 -187
- webscout/Provider/talkai.py +0 -194
- webscout/Provider/tutorai.py +0 -252
- webscout/Provider/typegpt.py +0 -232
- webscout/Provider/uncovr.py +0 -312
- webscout/Provider/yep.py +0 -376
- webscout/litprinter/__init__.py +0 -59
- webscout/scout/core.py +0 -881
- webscout/tempid.py +0 -128
- webscout/webscout_search.py +0 -1346
- webscout/webscout_search_async.py +0 -877
- webscout/yep_search.py +0 -297
- webscout-8.2.2.dist-info/METADATA +0 -734
- webscout-8.2.2.dist-info/RECORD +0 -309
- webscout-8.2.2.dist-info/entry_points.txt +0 -5
- webscout-8.2.2.dist-info/top_level.txt +0 -3
- webstoken/__init__.py +0 -30
- webstoken/classifier.py +0 -189
- webstoken/keywords.py +0 -216
- webstoken/language.py +0 -128
- webstoken/ner.py +0 -164
- webstoken/normalizer.py +0 -35
- webstoken/processor.py +0 -77
- webstoken/sentiment.py +0 -206
- webstoken/stemmer.py +0 -73
- webstoken/tagger.py +0 -60
- webstoken/tokenizer.py +0 -158
- {webscout-8.2.2.dist-info → webscout-2026.1.19.dist-info/licenses}/LICENSE.md +0 -0
webscout/Provider/AllenAI.py
DELETED
|
@@ -1,413 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
from uuid import uuid4
|
|
5
|
-
from typing import Any, Dict, Optional, Generator, Union
|
|
6
|
-
|
|
7
|
-
from webscout.AIutel import Optimizers
|
|
8
|
-
from webscout.AIutel import Conversation
|
|
9
|
-
from webscout.AIutel import AwesomePrompts, sanitize_stream
|
|
10
|
-
from webscout.AIbase import Provider, AsyncProvider
|
|
11
|
-
from webscout import exceptions
|
|
12
|
-
from webscout.litagent import LitAgent
|
|
13
|
-
|
|
14
|
-
class AllenAI(Provider):
|
|
15
|
-
"""
|
|
16
|
-
A class to interact with the AllenAI (Ai2 Playground) API.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
AVAILABLE_MODELS = [
|
|
20
|
-
'OLMo-2-1124-13B-Instruct',
|
|
21
|
-
'Llama-3-1-Tulu-3-8B',
|
|
22
|
-
'olmo-2-0325-32b-instruct',
|
|
23
|
-
'Llama-3-1-Tulu-3-70B',
|
|
24
|
-
'OLMoE-1B-7B-0924-Instruct',
|
|
25
|
-
'tulu3-405b',
|
|
26
|
-
'olmo-2-0325-32b-instruct',
|
|
27
|
-
'tulu-3-1-8b',
|
|
28
|
-
'olmoe-0125'
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
# Default model options from JS implementation
|
|
32
|
-
DEFAULT_OPTIONS = {
|
|
33
|
-
"max_tokens": 2048,
|
|
34
|
-
"temperature": 0.7,
|
|
35
|
-
"top_p": 1,
|
|
36
|
-
"n": 1,
|
|
37
|
-
"stop": None,
|
|
38
|
-
"logprobs": None
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
# Host mapping for models - some models work best with specific hosts
|
|
42
|
-
MODEL_HOST_MAP = {
|
|
43
|
-
'tulu3-405b': 'inferd',
|
|
44
|
-
'tulu2': 'inferd',
|
|
45
|
-
'olmo-7b-instruct': 'inferd'
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
def __init__(
|
|
49
|
-
self,
|
|
50
|
-
is_conversation: bool = True,
|
|
51
|
-
max_tokens: int = 2048,
|
|
52
|
-
timeout: int = 30,
|
|
53
|
-
intro: str = None,
|
|
54
|
-
filepath: str = None,
|
|
55
|
-
update_file: bool = True,
|
|
56
|
-
proxies: dict = {},
|
|
57
|
-
history_offset: int = 10250,
|
|
58
|
-
act: str = None,
|
|
59
|
-
model: str = "OLMo-2-1124-13B-Instruct",
|
|
60
|
-
host: str = None # Now optional - will auto-detect if not provided
|
|
61
|
-
):
|
|
62
|
-
"""Initializes the AllenAI API client."""
|
|
63
|
-
if model not in self.AVAILABLE_MODELS:
|
|
64
|
-
raise ValueError(f"Invalid model: {model}. Choose from: {self.AVAILABLE_MODELS}")
|
|
65
|
-
|
|
66
|
-
self.url = "https://playground.allenai.org"
|
|
67
|
-
# Updated API endpoint to v3 from v4
|
|
68
|
-
self.api_endpoint = "https://olmo-api.allen.ai/v3/message/stream"
|
|
69
|
-
self.whoami_endpoint = "https://olmo-api.allen.ai/v3/whoami"
|
|
70
|
-
|
|
71
|
-
# Updated headers based on JS implementation
|
|
72
|
-
self.headers = {
|
|
73
|
-
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",
|
|
74
|
-
'Accept': '*/*',
|
|
75
|
-
'Accept-Language': 'id-ID,id;q=0.9',
|
|
76
|
-
'Origin': self.url,
|
|
77
|
-
'Referer': f"{self.url}/",
|
|
78
|
-
'Connection': 'keep-alive',
|
|
79
|
-
'Cache-Control': 'no-cache',
|
|
80
|
-
'Pragma': 'no-cache',
|
|
81
|
-
'Priority': 'u=1, i',
|
|
82
|
-
'Sec-Fetch-Dest': 'empty',
|
|
83
|
-
'Sec-Fetch-Mode': 'cors',
|
|
84
|
-
'Sec-Fetch-Site': 'cross-site',
|
|
85
|
-
'sec-ch-ua': '"Chromium";v="131", "Not_A Brand";v="24", "Microsoft Edge Simulate";v="131", "Lemur";v="131"',
|
|
86
|
-
'sec-ch-ua-mobile': '?1',
|
|
87
|
-
'sec-ch-ua-platform': '"Android"',
|
|
88
|
-
'Content-Type': 'application/json'
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
self.session = requests.Session()
|
|
92
|
-
self.session.headers.update(self.headers)
|
|
93
|
-
self.session.proxies.update(proxies)
|
|
94
|
-
self.model = model
|
|
95
|
-
|
|
96
|
-
# Auto-detect host if not provided
|
|
97
|
-
if not host:
|
|
98
|
-
# Use the preferred host from the model-host map, or default to modal
|
|
99
|
-
self.host = self.MODEL_HOST_MAP.get(model, 'modal')
|
|
100
|
-
else:
|
|
101
|
-
self.host = host
|
|
102
|
-
|
|
103
|
-
self.is_conversation = is_conversation
|
|
104
|
-
self.max_tokens_to_sample = max_tokens
|
|
105
|
-
self.timeout = timeout
|
|
106
|
-
self.last_response = {}
|
|
107
|
-
# Generate user ID if needed
|
|
108
|
-
self.x_anonymous_user_id = None
|
|
109
|
-
self.parent = None
|
|
110
|
-
|
|
111
|
-
# Default options
|
|
112
|
-
self.options = self.DEFAULT_OPTIONS.copy()
|
|
113
|
-
self.options["max_tokens"] = max_tokens
|
|
114
|
-
|
|
115
|
-
self.__available_optimizers = (
|
|
116
|
-
method
|
|
117
|
-
for method in dir(Optimizers)
|
|
118
|
-
if callable(getattr(Optimizers, method)) and not method.startswith("__")
|
|
119
|
-
)
|
|
120
|
-
Conversation.intro = (
|
|
121
|
-
AwesomePrompts().get_act(
|
|
122
|
-
act, raise_not_found=True, default=None, case_insensitive=True
|
|
123
|
-
)
|
|
124
|
-
if act
|
|
125
|
-
else intro or Conversation.intro
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
self.conversation = Conversation(
|
|
129
|
-
is_conversation, self.max_tokens_to_sample, filepath, update_file
|
|
130
|
-
)
|
|
131
|
-
self.conversation.history_offset = history_offset
|
|
132
|
-
|
|
133
|
-
def whoami(self):
|
|
134
|
-
"""Gets or creates a user ID for authentication with Allen AI API"""
|
|
135
|
-
temp_id = str(uuid4())
|
|
136
|
-
headers = self.session.headers.copy()
|
|
137
|
-
headers.update({"x-anonymous-user-id": temp_id})
|
|
138
|
-
|
|
139
|
-
try:
|
|
140
|
-
response = self.session.get(
|
|
141
|
-
self.whoami_endpoint,
|
|
142
|
-
headers=headers,
|
|
143
|
-
timeout=self.timeout
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
if response.status_code == 200:
|
|
147
|
-
data = response.json()
|
|
148
|
-
self.x_anonymous_user_id = data.get("client", temp_id)
|
|
149
|
-
return data
|
|
150
|
-
else:
|
|
151
|
-
self.x_anonymous_user_id = temp_id
|
|
152
|
-
return {"client": temp_id}
|
|
153
|
-
|
|
154
|
-
except Exception as e:
|
|
155
|
-
self.x_anonymous_user_id = temp_id
|
|
156
|
-
return {"client": temp_id, "error": str(e)}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def parse_stream(self, raw_data):
|
|
160
|
-
"""Parse the raw streaming data according to the JS implementation"""
|
|
161
|
-
result = ""
|
|
162
|
-
for line in raw_data.splitlines():
|
|
163
|
-
try:
|
|
164
|
-
parsed = json.loads(line)
|
|
165
|
-
# Check if message starts with msg_ pattern
|
|
166
|
-
if parsed.get("message", "").startswith("msg_"):
|
|
167
|
-
result += parsed.get("content", "")
|
|
168
|
-
except:
|
|
169
|
-
continue
|
|
170
|
-
return result
|
|
171
|
-
|
|
172
|
-
def ask(
|
|
173
|
-
self,
|
|
174
|
-
prompt: str,
|
|
175
|
-
stream: bool = False,
|
|
176
|
-
raw: bool = False,
|
|
177
|
-
optimizer: str = None,
|
|
178
|
-
conversationally: bool = False,
|
|
179
|
-
host: str = None,
|
|
180
|
-
private: bool = False,
|
|
181
|
-
top_p: float = None,
|
|
182
|
-
temperature: float = None,
|
|
183
|
-
options: dict = None,
|
|
184
|
-
) -> Union[Dict[str, Any], Generator]:
|
|
185
|
-
conversation_prompt = self.conversation.gen_complete_prompt(prompt)
|
|
186
|
-
if optimizer:
|
|
187
|
-
if optimizer in self.__available_optimizers:
|
|
188
|
-
conversation_prompt = getattr(Optimizers, optimizer)(
|
|
189
|
-
conversation_prompt if conversationally else prompt
|
|
190
|
-
)
|
|
191
|
-
else:
|
|
192
|
-
raise Exception(f"Optimizer is not one of {self.__available_optimizers}")
|
|
193
|
-
|
|
194
|
-
# Ensure we have a user ID
|
|
195
|
-
if not self.x_anonymous_user_id:
|
|
196
|
-
self.whoami()
|
|
197
|
-
|
|
198
|
-
# Prepare the API request
|
|
199
|
-
self.session.headers.update({
|
|
200
|
-
"x-anonymous-user-id": self.x_anonymous_user_id,
|
|
201
|
-
"Content-Type": "application/json"
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
# Create options dictionary
|
|
205
|
-
opts = self.options.copy()
|
|
206
|
-
if temperature is not None:
|
|
207
|
-
opts["temperature"] = temperature
|
|
208
|
-
if top_p is not None:
|
|
209
|
-
opts["top_p"] = top_p
|
|
210
|
-
if options:
|
|
211
|
-
opts.update(options)
|
|
212
|
-
|
|
213
|
-
# Use the host param or the default host
|
|
214
|
-
use_host = host or self.host
|
|
215
|
-
|
|
216
|
-
# List of hosts to try - start with provided host, then try alternative hosts
|
|
217
|
-
hosts_to_try = [use_host]
|
|
218
|
-
if use_host == 'modal':
|
|
219
|
-
hosts_to_try.append('inferd')
|
|
220
|
-
else:
|
|
221
|
-
hosts_to_try.append('modal')
|
|
222
|
-
|
|
223
|
-
last_error = None
|
|
224
|
-
|
|
225
|
-
# Try each host until one works
|
|
226
|
-
for current_host in hosts_to_try:
|
|
227
|
-
# Create the JSON payload as per the JS implementation
|
|
228
|
-
payload = {
|
|
229
|
-
"content": conversation_prompt,
|
|
230
|
-
"private": private,
|
|
231
|
-
"model": self.model,
|
|
232
|
-
"host": current_host,
|
|
233
|
-
"opts": opts
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
# Add parent if exists
|
|
237
|
-
if self.parent:
|
|
238
|
-
payload["parent"] = self.parent
|
|
239
|
-
|
|
240
|
-
try:
|
|
241
|
-
if stream:
|
|
242
|
-
return self._stream_request(payload, prompt, raw)
|
|
243
|
-
else:
|
|
244
|
-
return self._non_stream_request(payload, prompt)
|
|
245
|
-
except exceptions.FailedToGenerateResponseError as e:
|
|
246
|
-
last_error = e
|
|
247
|
-
# Log the error but continue to try other hosts
|
|
248
|
-
print(f"Host '{current_host}' failed for model '{self.model}', trying next host...")
|
|
249
|
-
continue
|
|
250
|
-
|
|
251
|
-
# If we've tried all hosts and none worked, raise the last error
|
|
252
|
-
raise last_error or exceptions.FailedToGenerateResponseError("All hosts failed. Unable to complete request.")
|
|
253
|
-
|
|
254
|
-
def _stream_request(self, payload, prompt, raw=False):
|
|
255
|
-
"""Handle streaming requests with the given payload"""
|
|
256
|
-
try:
|
|
257
|
-
response = self.session.post(
|
|
258
|
-
self.api_endpoint,
|
|
259
|
-
json=payload,
|
|
260
|
-
stream=True,
|
|
261
|
-
timeout=self.timeout
|
|
262
|
-
)
|
|
263
|
-
|
|
264
|
-
if response.status_code != 200:
|
|
265
|
-
raise exceptions.FailedToGenerateResponseError(
|
|
266
|
-
f"Request failed with status code {response.status_code}: {response.text}"
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
streaming_text = ""
|
|
270
|
-
current_parent = None
|
|
271
|
-
|
|
272
|
-
for chunk in response.iter_content(chunk_size=1024, decode_unicode=False):
|
|
273
|
-
if not chunk:
|
|
274
|
-
continue
|
|
275
|
-
|
|
276
|
-
decoded = chunk.decode(errors="ignore")
|
|
277
|
-
for line in decoded.splitlines():
|
|
278
|
-
line = line.strip()
|
|
279
|
-
if not line:
|
|
280
|
-
continue
|
|
281
|
-
|
|
282
|
-
try:
|
|
283
|
-
data = json.loads(line)
|
|
284
|
-
except json.JSONDecodeError:
|
|
285
|
-
continue
|
|
286
|
-
|
|
287
|
-
if isinstance(data, dict):
|
|
288
|
-
# Check for message pattern from JS implementation
|
|
289
|
-
if data.get("message", "").startswith("msg_") and "content" in data:
|
|
290
|
-
content = data.get("content", "")
|
|
291
|
-
if content:
|
|
292
|
-
streaming_text += content
|
|
293
|
-
resp = dict(text=content)
|
|
294
|
-
yield resp if raw else resp
|
|
295
|
-
|
|
296
|
-
# Legacy handling for older API
|
|
297
|
-
elif "message" in data and data.get("content"):
|
|
298
|
-
content = data.get("content")
|
|
299
|
-
if content.strip():
|
|
300
|
-
streaming_text += content
|
|
301
|
-
resp = dict(text=content)
|
|
302
|
-
yield resp if raw else resp
|
|
303
|
-
|
|
304
|
-
# Update parent ID if present
|
|
305
|
-
if data.get("id"):
|
|
306
|
-
current_parent = data.get("id")
|
|
307
|
-
elif data.get("children"):
|
|
308
|
-
for child in data["children"]:
|
|
309
|
-
if child.get("role") == "assistant":
|
|
310
|
-
current_parent = child.get("id")
|
|
311
|
-
break
|
|
312
|
-
|
|
313
|
-
# Handle completion
|
|
314
|
-
if data.get("final") or data.get("finish_reason") == "stop":
|
|
315
|
-
if current_parent:
|
|
316
|
-
self.parent = current_parent
|
|
317
|
-
|
|
318
|
-
# Update conversation history
|
|
319
|
-
self.conversation.update_chat_history(prompt, streaming_text)
|
|
320
|
-
self.last_response = {"text": streaming_text}
|
|
321
|
-
return
|
|
322
|
-
|
|
323
|
-
except requests.RequestException as e:
|
|
324
|
-
raise exceptions.FailedToGenerateResponseError(f"Request failed: {str(e)}")
|
|
325
|
-
|
|
326
|
-
def _non_stream_request(self, payload, prompt):
|
|
327
|
-
"""Handle non-streaming requests with the given payload"""
|
|
328
|
-
try:
|
|
329
|
-
# For non-streaming requests, we can directly send without stream=True
|
|
330
|
-
response = self.session.post(
|
|
331
|
-
self.api_endpoint,
|
|
332
|
-
json=payload,
|
|
333
|
-
stream=False,
|
|
334
|
-
timeout=self.timeout
|
|
335
|
-
)
|
|
336
|
-
|
|
337
|
-
if response.status_code != 200:
|
|
338
|
-
raise exceptions.FailedToGenerateResponseError(
|
|
339
|
-
f"Request failed with status code {response.status_code}: {response.text}"
|
|
340
|
-
)
|
|
341
|
-
|
|
342
|
-
# Parse the response as per JS implementation
|
|
343
|
-
raw_response = response.text
|
|
344
|
-
parsed_response = self.parse_stream(raw_response)
|
|
345
|
-
self.conversation.update_chat_history(prompt, parsed_response)
|
|
346
|
-
self.last_response = {"text": parsed_response}
|
|
347
|
-
return self.last_response
|
|
348
|
-
|
|
349
|
-
except Exception as e:
|
|
350
|
-
raise exceptions.FailedToGenerateResponseError(f"Request failed: {str(e)}")
|
|
351
|
-
|
|
352
|
-
def chat(
|
|
353
|
-
self,
|
|
354
|
-
prompt: str,
|
|
355
|
-
stream: bool = False,
|
|
356
|
-
optimizer: str = None,
|
|
357
|
-
conversationally: bool = False,
|
|
358
|
-
host: str = None,
|
|
359
|
-
options: dict = None,
|
|
360
|
-
) -> str:
|
|
361
|
-
def for_stream():
|
|
362
|
-
for response in self.ask(
|
|
363
|
-
prompt,
|
|
364
|
-
True,
|
|
365
|
-
optimizer=optimizer,
|
|
366
|
-
conversationally=conversationally,
|
|
367
|
-
host=host,
|
|
368
|
-
options=options
|
|
369
|
-
):
|
|
370
|
-
yield self.get_message(response)
|
|
371
|
-
def for_non_stream():
|
|
372
|
-
return self.get_message(
|
|
373
|
-
self.ask(
|
|
374
|
-
prompt,
|
|
375
|
-
False,
|
|
376
|
-
optimizer=optimizer,
|
|
377
|
-
conversationally=conversationally,
|
|
378
|
-
host=host,
|
|
379
|
-
options=options
|
|
380
|
-
)
|
|
381
|
-
)
|
|
382
|
-
return for_stream() if stream else for_non_stream()
|
|
383
|
-
|
|
384
|
-
def get_message(self, response: dict) -> str:
|
|
385
|
-
assert isinstance(response, dict), "Response should be of dict data-type only"
|
|
386
|
-
return response["text"]
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if __name__ == "__main__":
|
|
391
|
-
print("-" * 80)
|
|
392
|
-
print(f"{'Model':<50} {'Status':<10} {'Response'}")
|
|
393
|
-
print("-" * 80)
|
|
394
|
-
|
|
395
|
-
for model in AllenAI.AVAILABLE_MODELS:
|
|
396
|
-
try:
|
|
397
|
-
# Auto-detect host
|
|
398
|
-
test_ai = AllenAI(model=model, timeout=60)
|
|
399
|
-
# Pass the host explicitly to display accurate error messages
|
|
400
|
-
response = test_ai.chat("Say 'Hello' in one word")
|
|
401
|
-
response_text = response
|
|
402
|
-
|
|
403
|
-
if response_text and len(response_text.strip()) > 0:
|
|
404
|
-
status = "✓"
|
|
405
|
-
# Truncate response if too long
|
|
406
|
-
display_text = response_text.strip()[:50] + "..." if len(response_text.strip()) > 50 else response_text.strip()
|
|
407
|
-
print(f"{model:<50} {status:<10} {display_text} (host: {test_ai.host})")
|
|
408
|
-
else:
|
|
409
|
-
status = "✗"
|
|
410
|
-
display_text = "Empty or invalid response"
|
|
411
|
-
print(f"{model:<50} {status:<10} {display_text}")
|
|
412
|
-
except Exception as e:
|
|
413
|
-
print(f"{model:<50} {'✗':<10} {str(e)}")
|
webscout/Provider/Blackboxai.py
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
import json
|
|
3
|
-
from typing import Any, Dict, Optional, Union, Generator, List
|
|
4
|
-
from webscout.AIutel import Optimizers, Conversation, AwesomePrompts
|
|
5
|
-
from webscout.AIbase import Provider
|
|
6
|
-
from webscout import exceptions
|
|
7
|
-
from webscout.Litlogger import Logger, LogFormat
|
|
8
|
-
|
|
9
|
-
class BLACKBOXAI(Provider):
|
|
10
|
-
"""
|
|
11
|
-
BlackboxAI provider for interacting with the Blackbox API.
|
|
12
|
-
Supports synchronous operations with multiple models.
|
|
13
|
-
"""
|
|
14
|
-
url = "https://api.blackbox.ai"
|
|
15
|
-
api_endpoint = "https://api.blackbox.ai/api/chat"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
AVAILABLE_MODELS = {
|
|
20
|
-
"deepseek-v3": "deepseek-ai/DeepSeek-V3",
|
|
21
|
-
"deepseek-r1": "deepseek-ai/DeepSeek-R1",
|
|
22
|
-
"deepseek-chat": "deepseek-ai/deepseek-llm-67b-chat",
|
|
23
|
-
"mixtral-small-28b": "mistralai/Mistral-Small-24B-Instruct-2501",
|
|
24
|
-
"dbrx-instruct": "databricks/dbrx-instruct",
|
|
25
|
-
"qwq-32b": "Qwen/QwQ-32B-Preview",
|
|
26
|
-
"hermes-2-dpo": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
|
|
27
|
-
"claude-3.5-sonnet": "claude-sonnet-3.5",
|
|
28
|
-
"gemini-1.5-flash": "gemini-1.5-flash",
|
|
29
|
-
"gemini-1.5-pro": "gemini-pro",
|
|
30
|
-
"gemini-2.0-flash": "Gemini-Flash-2.0",
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
def __init__(
|
|
34
|
-
self,
|
|
35
|
-
is_conversation: bool = True,
|
|
36
|
-
max_tokens: int = 8000,
|
|
37
|
-
timeout: int = 30,
|
|
38
|
-
intro: str = None,
|
|
39
|
-
filepath: str = None,
|
|
40
|
-
update_file: bool = True,
|
|
41
|
-
proxies: dict = {},
|
|
42
|
-
history_offset: int = 10250,
|
|
43
|
-
act: str = None,
|
|
44
|
-
model: str = "deepseek-ai/DeepSeek-V3",
|
|
45
|
-
logging: bool = False,
|
|
46
|
-
system_message: str = "You are a helpful AI assistant."
|
|
47
|
-
):
|
|
48
|
-
"""Initialize BlackboxAI with enhanced configuration options."""
|
|
49
|
-
self.logger = Logger(
|
|
50
|
-
name="BlackboxAI",
|
|
51
|
-
format=LogFormat.MODERN_EMOJI,
|
|
52
|
-
|
|
53
|
-
) if logging else None
|
|
54
|
-
|
|
55
|
-
self.session = requests.Session()
|
|
56
|
-
self.max_tokens_to_sample = max_tokens
|
|
57
|
-
self.is_conversation = is_conversation
|
|
58
|
-
self.timeout = timeout
|
|
59
|
-
self.last_response = {}
|
|
60
|
-
self.model = self.get_model(model)
|
|
61
|
-
self.system_message = system_message
|
|
62
|
-
|
|
63
|
-
self.headers = {
|
|
64
|
-
"Content-Type": "application/json",
|
|
65
|
-
"Accept": "*/*",
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if self.logger:
|
|
69
|
-
self.logger.info(f"Initializing BlackboxAI with model: {self.model}")
|
|
70
|
-
|
|
71
|
-
self.__available_optimizers = (
|
|
72
|
-
method for method in dir(Optimizers)
|
|
73
|
-
if callable(getattr(Optimizers, method)) and not method.startswith("__")
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
Conversation.intro = (
|
|
77
|
-
AwesomePrompts().get_act(
|
|
78
|
-
act, raise_not_found=True, default=None, case_insensitive=True
|
|
79
|
-
)
|
|
80
|
-
if act
|
|
81
|
-
else intro or Conversation.intro
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
self.conversation = Conversation(
|
|
85
|
-
is_conversation, self.max_tokens_to_sample, filepath, update_file
|
|
86
|
-
)
|
|
87
|
-
self.conversation.history_offset = history_offset
|
|
88
|
-
self.session.proxies = proxies
|
|
89
|
-
|
|
90
|
-
@classmethod
|
|
91
|
-
def get_model(self, model: str) -> str:
|
|
92
|
-
"""Resolve model name from alias"""
|
|
93
|
-
if model in self.AVAILABLE_MODELS:
|
|
94
|
-
return self.AVAILABLE_MODELS[model]
|
|
95
|
-
raise ValueError(f"Unknown model: {model}. Available models: {', '.join(self.AVAILABLE_MODELS)}")
|
|
96
|
-
|
|
97
|
-
def _make_request(
|
|
98
|
-
self,
|
|
99
|
-
messages: List[Dict[str, str]],
|
|
100
|
-
stream: bool = False
|
|
101
|
-
) -> Generator[str, None, None]:
|
|
102
|
-
"""Make synchronous request to BlackboxAI API."""
|
|
103
|
-
if self.logger:
|
|
104
|
-
self.logger.debug(f"Making request with {len(messages)} messages")
|
|
105
|
-
|
|
106
|
-
data = {
|
|
107
|
-
"messages": messages,
|
|
108
|
-
"model": self.model,
|
|
109
|
-
"max_tokens": self.max_tokens_to_sample
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
try:
|
|
113
|
-
response = self.session.post(
|
|
114
|
-
self.api_endpoint,
|
|
115
|
-
json=data,
|
|
116
|
-
headers=self.headers,
|
|
117
|
-
stream=stream,
|
|
118
|
-
timeout=self.timeout
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
if not response.ok:
|
|
122
|
-
error_msg = f"API request failed: {response.status_code} - {response.text}"
|
|
123
|
-
if self.logger:
|
|
124
|
-
self.logger.error(error_msg)
|
|
125
|
-
raise exceptions.FailedToGenerateResponseError(error_msg)
|
|
126
|
-
|
|
127
|
-
if stream:
|
|
128
|
-
for line in response.iter_lines(decode_unicode=True):
|
|
129
|
-
if line:
|
|
130
|
-
yield line
|
|
131
|
-
else:
|
|
132
|
-
yield response.text
|
|
133
|
-
|
|
134
|
-
except requests.exceptions.RequestException as e:
|
|
135
|
-
if self.logger:
|
|
136
|
-
self.logger.error(f"Request failed: {str(e)}")
|
|
137
|
-
raise exceptions.ProviderConnectionError(f"Connection error: {str(e)}")
|
|
138
|
-
|
|
139
|
-
def ask(
|
|
140
|
-
self,
|
|
141
|
-
prompt: str,
|
|
142
|
-
stream: bool = False,
|
|
143
|
-
raw: bool = False,
|
|
144
|
-
optimizer: str = None,
|
|
145
|
-
conversationally: bool = False,
|
|
146
|
-
) -> Union[Dict[str, str], Generator[Dict[str, str], None, None]]:
|
|
147
|
-
"""Send a prompt to BlackboxAI API and return the response."""
|
|
148
|
-
if self.logger:
|
|
149
|
-
self.logger.debug(f"Processing request [stream={stream}]")
|
|
150
|
-
|
|
151
|
-
conversation_prompt = self.conversation.gen_complete_prompt(prompt)
|
|
152
|
-
if optimizer:
|
|
153
|
-
if optimizer in self.__available_optimizers:
|
|
154
|
-
conversation_prompt = getattr(Optimizers, optimizer)(
|
|
155
|
-
conversation_prompt if conversationally else prompt
|
|
156
|
-
)
|
|
157
|
-
if self.logger:
|
|
158
|
-
self.logger.debug(f"Applied optimizer: {optimizer}")
|
|
159
|
-
else:
|
|
160
|
-
if self.logger:
|
|
161
|
-
self.logger.error(f"Invalid optimizer: {optimizer}")
|
|
162
|
-
raise ValueError(f"Optimizer is not one of {self.__available_optimizers}")
|
|
163
|
-
|
|
164
|
-
messages = [
|
|
165
|
-
{"role": "system", "content": self.system_message},
|
|
166
|
-
{"role": "user", "content": conversation_prompt}
|
|
167
|
-
]
|
|
168
|
-
|
|
169
|
-
def for_stream():
|
|
170
|
-
for text in self._make_request(messages, stream=True):
|
|
171
|
-
yield {"text": text}
|
|
172
|
-
|
|
173
|
-
def for_non_stream():
|
|
174
|
-
response_text = next(self._make_request(messages, stream=False))
|
|
175
|
-
self.last_response = {"text": response_text}
|
|
176
|
-
return self.last_response
|
|
177
|
-
|
|
178
|
-
return for_stream() if stream else for_non_stream()
|
|
179
|
-
|
|
180
|
-
def chat(
|
|
181
|
-
self,
|
|
182
|
-
prompt: str,
|
|
183
|
-
stream: bool = False,
|
|
184
|
-
optimizer: str = None,
|
|
185
|
-
conversationally: bool = False,
|
|
186
|
-
) -> Union[str, Generator[str, None, None]]:
|
|
187
|
-
"""Generate response as string."""
|
|
188
|
-
if self.logger:
|
|
189
|
-
self.logger.debug(f"Chat request initiated [stream={stream}]")
|
|
190
|
-
|
|
191
|
-
def for_stream():
|
|
192
|
-
for response in self.ask(
|
|
193
|
-
prompt,
|
|
194
|
-
stream=True,
|
|
195
|
-
optimizer=optimizer,
|
|
196
|
-
conversationally=conversationally
|
|
197
|
-
):
|
|
198
|
-
yield self.get_message(response)
|
|
199
|
-
|
|
200
|
-
def for_non_stream():
|
|
201
|
-
return self.get_message(
|
|
202
|
-
self.ask(
|
|
203
|
-
prompt,
|
|
204
|
-
stream=False,
|
|
205
|
-
optimizer=optimizer,
|
|
206
|
-
conversationally=conversationally,
|
|
207
|
-
)
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
return for_stream() if stream else for_non_stream()
|
|
211
|
-
|
|
212
|
-
def get_message(self, response: Dict[str, Any]) -> str:
|
|
213
|
-
"""Extract message from response dictionary."""
|
|
214
|
-
assert isinstance(response, dict), "Response should be of dict data-type only"
|
|
215
|
-
return response["text"].replace('\\n', '\n').replace('\\n\\n', '\n\n')
|
|
216
|
-
|
|
217
|
-
if __name__ == "__main__":
|
|
218
|
-
from rich import print
|
|
219
|
-
|
|
220
|
-
# Example usage
|
|
221
|
-
ai = BLACKBOXAI(model="deepseek-v3", logging=True)
|
|
222
|
-
|
|
223
|
-
try:
|
|
224
|
-
print("Non-streaming response:")
|
|
225
|
-
response = ai.chat("What is quantum computing?")
|
|
226
|
-
print(response)
|
|
227
|
-
|
|
228
|
-
except Exception as e:
|
|
229
|
-
print(f"Error: {str(e)}")
|