webscout 8.2.9__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 -251
- webscout/AIbase.py +247 -319
- webscout/AIutel.py +68 -703
- webscout/Bard.py +1072 -1026
- webscout/Extra/GitToolkit/__init__.py +10 -10
- 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 -375
- 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 -44
- 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 -118
- 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 +403 -232
- webscout/Extra/__init__.py +2 -3
- webscout/Extra/gguf.py +1298 -684
- webscout/Extra/tempmail/README.md +487 -487
- 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 +292 -333
- webscout/Provider/AISEARCH/README.md +106 -279
- webscout/Provider/AISEARCH/__init__.py +16 -9
- webscout/Provider/AISEARCH/brave_search.py +298 -0
- webscout/Provider/AISEARCH/iask_search.py +357 -410
- webscout/Provider/AISEARCH/monica_search.py +200 -220
- webscout/Provider/AISEARCH/webpilotai_search.py +242 -255
- 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 -342
- webscout/Provider/ClaudeOnline.py +365 -0
- webscout/Provider/Cohere.py +232 -208
- webscout/Provider/DeepAI.py +367 -0
- webscout/Provider/Deepinfra.py +467 -340
- webscout/Provider/EssentialAI.py +217 -0
- webscout/Provider/ExaAI.py +274 -261
- webscout/Provider/Gemini.py +175 -169
- webscout/Provider/GithubChat.py +385 -369
- webscout/Provider/Gradient.py +286 -0
- webscout/Provider/Groq.py +556 -801
- webscout/Provider/HadadXYZ.py +323 -0
- webscout/Provider/HeckAI.py +392 -375
- webscout/Provider/HuggingFace.py +387 -0
- webscout/Provider/IBM.py +340 -0
- webscout/Provider/Jadve.py +317 -291
- webscout/Provider/K2Think.py +306 -0
- webscout/Provider/Koboldai.py +221 -384
- webscout/Provider/Netwrck.py +273 -270
- 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 -952
- webscout/Provider/OPENAI/TogetherAI.py +405 -0
- webscout/Provider/OPENAI/TwoAI.py +255 -357
- webscout/Provider/OPENAI/__init__.py +148 -40
- webscout/Provider/OPENAI/ai4chat.py +348 -293
- webscout/Provider/OPENAI/akashgpt.py +436 -0
- webscout/Provider/OPENAI/algion.py +303 -0
- webscout/Provider/OPENAI/{exachat.py → ayle.py} +365 -444
- webscout/Provider/OPENAI/base.py +253 -249
- webscout/Provider/OPENAI/cerebras.py +296 -0
- webscout/Provider/OPENAI/chatgpt.py +870 -556
- webscout/Provider/OPENAI/chatsandbox.py +233 -173
- webscout/Provider/OPENAI/deepinfra.py +403 -322
- webscout/Provider/OPENAI/e2b.py +2370 -1414
- webscout/Provider/OPENAI/elmo.py +278 -0
- webscout/Provider/OPENAI/exaai.py +452 -417
- webscout/Provider/OPENAI/freeassist.py +446 -0
- webscout/Provider/OPENAI/gradient.py +448 -0
- webscout/Provider/OPENAI/groq.py +380 -364
- webscout/Provider/OPENAI/hadadxyz.py +292 -0
- webscout/Provider/OPENAI/heckai.py +333 -308
- 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 -335
- webscout/Provider/OPENAI/meta.py +541 -0
- webscout/Provider/OPENAI/netwrck.py +374 -357
- webscout/Provider/OPENAI/nvidia.py +317 -0
- webscout/Provider/OPENAI/oivscode.py +348 -287
- webscout/Provider/OPENAI/openrouter.py +328 -0
- webscout/Provider/OPENAI/pydantic_imports.py +1 -172
- webscout/Provider/OPENAI/sambanova.py +397 -0
- webscout/Provider/OPENAI/sonus.py +305 -304
- webscout/Provider/OPENAI/textpollinations.py +370 -339
- webscout/Provider/OPENAI/toolbaz.py +375 -413
- webscout/Provider/OPENAI/typefully.py +419 -355
- webscout/Provider/OPENAI/typliai.py +279 -0
- webscout/Provider/OPENAI/utils.py +314 -318
- webscout/Provider/OPENAI/wisecat.py +359 -387
- webscout/Provider/OPENAI/writecream.py +185 -163
- webscout/Provider/OPENAI/x0gpt.py +462 -365
- webscout/Provider/OPENAI/zenmux.py +380 -0
- webscout/Provider/OpenRouter.py +386 -0
- webscout/Provider/Openai.py +337 -496
- webscout/Provider/PI.py +443 -429
- 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 -82
- webscout/Provider/TTI/__init__.py +37 -7
- webscout/Provider/TTI/base.py +147 -64
- webscout/Provider/TTI/claudeonline.py +393 -0
- webscout/Provider/TTI/magicstudio.py +292 -201
- webscout/Provider/TTI/miragic.py +180 -0
- webscout/Provider/TTI/pollinations.py +331 -221
- webscout/Provider/TTI/together.py +334 -0
- webscout/Provider/TTI/utils.py +14 -11
- webscout/Provider/TTS/README.md +186 -192
- webscout/Provider/TTS/__init__.py +43 -10
- webscout/Provider/TTS/base.py +523 -159
- 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 -129
- 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 -580
- webscout/Provider/TTS/streamElements.py +275 -333
- webscout/Provider/TTS/utils.py +280 -280
- webscout/Provider/TextPollinationsAI.py +331 -308
- webscout/Provider/TogetherAI.py +450 -0
- webscout/Provider/TwoAI.py +309 -475
- webscout/Provider/TypliAI.py +311 -305
- webscout/Provider/UNFINISHED/ChatHub.py +219 -209
- webscout/Provider/{OPENAI/glider.py → UNFINISHED/ChutesAI.py} +331 -326
- webscout/Provider/{GizAI.py → UNFINISHED/GizAI.py} +300 -295
- webscout/Provider/{Marcus.py → UNFINISHED/Marcus.py} +218 -198
- webscout/Provider/UNFINISHED/Qodo.py +481 -0
- webscout/Provider/{MCPCore.py → UNFINISHED/XenAI.py} +330 -315
- webscout/Provider/UNFINISHED/Youchat.py +347 -330
- 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 -263
- webscout/Provider/{samurai.py → UNFINISHED/samurai.py} +231 -224
- webscout/Provider/WiseCat.py +256 -233
- webscout/Provider/WrDoChat.py +390 -370
- webscout/Provider/__init__.py +115 -174
- webscout/Provider/ai4chat.py +181 -174
- webscout/Provider/akashgpt.py +330 -335
- webscout/Provider/cerebras.py +397 -290
- webscout/Provider/cleeai.py +236 -213
- webscout/Provider/elmo.py +291 -283
- webscout/Provider/geminiapi.py +343 -208
- webscout/Provider/julius.py +245 -223
- webscout/Provider/learnfastai.py +333 -325
- webscout/Provider/llama3mitril.py +230 -215
- webscout/Provider/llmchat.py +308 -258
- webscout/Provider/llmchatco.py +321 -306
- webscout/Provider/meta.py +996 -801
- webscout/Provider/oivscode.py +332 -309
- webscout/Provider/searchchat.py +316 -292
- webscout/Provider/sonus.py +264 -258
- webscout/Provider/toolbaz.py +359 -353
- webscout/Provider/turboseek.py +332 -266
- webscout/Provider/typefully.py +262 -202
- webscout/Provider/x0gpt.py +332 -299
- webscout/__init__.py +31 -39
- webscout/__main__.py +5 -5
- webscout/cli.py +585 -524
- webscout/client.py +1497 -70
- webscout/conversation.py +140 -436
- webscout/exceptions.py +383 -362
- 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 +74 -420
- webscout/prompt_manager.py +376 -288
- webscout/sanitize.py +1514 -0
- webscout/scout/README.md +452 -404
- webscout/scout/__init__.py +8 -8
- webscout/scout/core/__init__.py +7 -7
- webscout/scout/core/crawler.py +330 -210
- webscout/scout/core/scout.py +800 -607
- 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 -478
- 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 -95
- webscout/swiftcli/core/__init__.py +7 -7
- webscout/swiftcli/core/cli.py +574 -297
- webscout/swiftcli/core/context.py +98 -104
- webscout/swiftcli/core/group.py +268 -241
- webscout/swiftcli/decorators/__init__.py +28 -28
- webscout/swiftcli/decorators/command.py +243 -221
- webscout/swiftcli/decorators/options.py +247 -220
- webscout/swiftcli/decorators/output.py +392 -252
- webscout/swiftcli/exceptions.py +21 -21
- webscout/swiftcli/plugins/__init__.py +9 -9
- webscout/swiftcli/plugins/base.py +134 -135
- webscout/swiftcli/plugins/manager.py +269 -269
- webscout/swiftcli/utils/__init__.py +58 -59
- webscout/swiftcli/utils/formatting.py +251 -252
- webscout/swiftcli/utils/parsing.py +368 -267
- 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 -135
- webscout/zeroart/base.py +70 -66
- webscout/zeroart/effects.py +155 -101
- webscout/zeroart/fonts.py +1799 -1239
- webscout-2026.1.19.dist-info/METADATA +638 -0
- webscout-2026.1.19.dist-info/RECORD +312 -0
- {webscout-8.2.9.dist-info → webscout-2026.1.19.dist-info}/WHEEL +1 -1
- {webscout-8.2.9.dist-info → webscout-2026.1.19.dist-info}/entry_points.txt +1 -1
- webscout/DWEBS.py +0 -520
- webscout/Extra/Act.md +0 -309
- webscout/Extra/GitToolkit/gitapi/README.md +0 -110
- webscout/Extra/autocoder/__init__.py +0 -9
- webscout/Extra/autocoder/autocoder.py +0 -1105
- webscout/Extra/autocoder/autocoder_utiles.py +0 -332
- webscout/Extra/gguf.md +0 -430
- webscout/Extra/weather.md +0 -281
- webscout/Litlogger/README.md +0 -10
- webscout/Litlogger/__init__.py +0 -15
- webscout/Litlogger/formats.py +0 -4
- webscout/Litlogger/handlers.py +0 -103
- webscout/Litlogger/levels.py +0 -13
- webscout/Litlogger/logger.py +0 -92
- webscout/Provider/AI21.py +0 -177
- webscout/Provider/AISEARCH/DeepFind.py +0 -254
- webscout/Provider/AISEARCH/felo_search.py +0 -202
- webscout/Provider/AISEARCH/genspark_search.py +0 -324
- webscout/Provider/AISEARCH/hika_search.py +0 -186
- webscout/Provider/AISEARCH/scira_search.py +0 -298
- webscout/Provider/Aitopia.py +0 -316
- webscout/Provider/AllenAI.py +0 -440
- webscout/Provider/Blackboxai.py +0 -791
- webscout/Provider/ChatGPTClone.py +0 -237
- webscout/Provider/ChatGPTGratis.py +0 -194
- webscout/Provider/Cloudflare.py +0 -324
- webscout/Provider/ExaChat.py +0 -358
- webscout/Provider/Flowith.py +0 -217
- webscout/Provider/FreeGemini.py +0 -250
- webscout/Provider/Glider.py +0 -225
- webscout/Provider/HF_space/__init__.py +0 -0
- webscout/Provider/HF_space/qwen_qwen2.py +0 -206
- webscout/Provider/HuggingFaceChat.py +0 -469
- webscout/Provider/Hunyuan.py +0 -283
- webscout/Provider/LambdaChat.py +0 -411
- webscout/Provider/Llama3.py +0 -259
- webscout/Provider/Nemotron.py +0 -218
- webscout/Provider/OLLAMA.py +0 -396
- webscout/Provider/OPENAI/BLACKBOXAI.py +0 -766
- webscout/Provider/OPENAI/Cloudflare.py +0 -378
- webscout/Provider/OPENAI/FreeGemini.py +0 -283
- webscout/Provider/OPENAI/NEMOTRON.py +0 -232
- webscout/Provider/OPENAI/Qwen3.py +0 -283
- webscout/Provider/OPENAI/api.py +0 -969
- webscout/Provider/OPENAI/c4ai.py +0 -373
- webscout/Provider/OPENAI/chatgptclone.py +0 -494
- webscout/Provider/OPENAI/copilot.py +0 -242
- webscout/Provider/OPENAI/flowith.py +0 -162
- webscout/Provider/OPENAI/freeaichat.py +0 -359
- webscout/Provider/OPENAI/mcpcore.py +0 -389
- webscout/Provider/OPENAI/multichat.py +0 -376
- webscout/Provider/OPENAI/opkfc.py +0 -496
- webscout/Provider/OPENAI/scirachat.py +0 -477
- webscout/Provider/OPENAI/standardinput.py +0 -433
- webscout/Provider/OPENAI/typegpt.py +0 -364
- webscout/Provider/OPENAI/uncovrAI.py +0 -463
- webscout/Provider/OPENAI/venice.py +0 -431
- webscout/Provider/OPENAI/yep.py +0 -382
- webscout/Provider/OpenGPT.py +0 -209
- webscout/Provider/Perplexitylabs.py +0 -415
- webscout/Provider/Reka.py +0 -214
- webscout/Provider/StandardInput.py +0 -290
- webscout/Provider/TTI/aiarta.py +0 -365
- webscout/Provider/TTI/artbit.py +0 -0
- webscout/Provider/TTI/fastflux.py +0 -200
- webscout/Provider/TTI/piclumen.py +0 -203
- webscout/Provider/TTI/pixelmuse.py +0 -225
- webscout/Provider/TTS/gesserit.py +0 -128
- webscout/Provider/TTS/sthir.py +0 -94
- webscout/Provider/TeachAnything.py +0 -229
- webscout/Provider/UNFINISHED/puterjs.py +0 -635
- webscout/Provider/UNFINISHED/test_lmarena.py +0 -119
- webscout/Provider/Venice.py +0 -258
- webscout/Provider/VercelAI.py +0 -253
- webscout/Provider/Writecream.py +0 -246
- webscout/Provider/WritingMate.py +0 -269
- webscout/Provider/asksteve.py +0 -220
- webscout/Provider/chatglm.py +0 -215
- webscout/Provider/copilot.py +0 -425
- webscout/Provider/freeaichat.py +0 -285
- webscout/Provider/granite.py +0 -235
- webscout/Provider/hermes.py +0 -266
- webscout/Provider/koala.py +0 -170
- webscout/Provider/lmarena.py +0 -198
- webscout/Provider/multichat.py +0 -364
- webscout/Provider/scira_chat.py +0 -299
- webscout/Provider/scnet.py +0 -243
- webscout/Provider/talkai.py +0 -194
- webscout/Provider/typegpt.py +0 -289
- webscout/Provider/uncovr.py +0 -368
- webscout/Provider/yep.py +0 -389
- webscout/litagent/Readme.md +0 -276
- webscout/litprinter/__init__.py +0 -59
- webscout/swiftcli/Readme.md +0 -323
- webscout/tempid.py +0 -128
- webscout/webscout_search.py +0 -1184
- webscout/webscout_search_async.py +0 -654
- webscout/yep_search.py +0 -347
- webscout/zeroart/README.md +0 -89
- webscout-8.2.9.dist-info/METADATA +0 -1033
- webscout-8.2.9.dist-info/RECORD +0 -289
- {webscout-8.2.9.dist-info → webscout-2026.1.19.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.2.9.dist-info → webscout-2026.1.19.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Any, Dict, Generator, List, Optional, Union, cast
|
|
3
|
+
|
|
4
|
+
from curl_cffi import CurlError
|
|
5
|
+
from curl_cffi.requests import Session
|
|
6
|
+
|
|
7
|
+
from webscout import exceptions
|
|
8
|
+
from webscout.AIbase import Provider, Response
|
|
9
|
+
from webscout.AIutel import AwesomePrompts, Conversation, Optimizers, sanitize_stream
|
|
10
|
+
from webscout.litagent import LitAgent as Lit
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Sambanova(Provider):
|
|
14
|
+
"""
|
|
15
|
+
A class to interact with the Sambanova API.
|
|
16
|
+
"""
|
|
17
|
+
required_auth = True
|
|
18
|
+
AVAILABLE_MODELS = [
|
|
19
|
+
"DeepSeek-R1",
|
|
20
|
+
"DeepSeek-V3",
|
|
21
|
+
"Meta-Llama-3.3-70B-Instruct",
|
|
22
|
+
"Meta-Llama-3.1-8B-Instruct",
|
|
23
|
+
"Meta-Llama-3.1-70B-Instruct",
|
|
24
|
+
"Meta-Llama-3.1-405B-Instruct",
|
|
25
|
+
"Qwen2.5-72B-Instruct",
|
|
26
|
+
"Qwen2.5-Coder-32B-Instruct"
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
def update_available_models(self):
|
|
30
|
+
"""Update the available models list from Sambanova API."""
|
|
31
|
+
if not self.api_key:
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
temp_session = Session()
|
|
36
|
+
headers = {
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
response = temp_session.get(
|
|
42
|
+
"https://api.sambanova.ai/v1/models",
|
|
43
|
+
headers=headers,
|
|
44
|
+
impersonate="chrome120"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if response.status_code == 200:
|
|
48
|
+
data = response.json()
|
|
49
|
+
if "data" in data and isinstance(data["data"], list):
|
|
50
|
+
new_models = [model['id'] for model in data['data'] if 'id' in model]
|
|
51
|
+
if new_models:
|
|
52
|
+
self.AVAILABLE_MODELS = new_models
|
|
53
|
+
|
|
54
|
+
except Exception:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
def __init__(
|
|
58
|
+
self,
|
|
59
|
+
api_key: Optional[str] = None,
|
|
60
|
+
is_conversation: bool = True,
|
|
61
|
+
max_tokens: int = 4096,
|
|
62
|
+
timeout: int = 30,
|
|
63
|
+
intro: Optional[str] = None,
|
|
64
|
+
filepath: Optional[str] = None,
|
|
65
|
+
update_file: bool = True,
|
|
66
|
+
proxies: dict = {},
|
|
67
|
+
history_offset: int = 10250,
|
|
68
|
+
act: Optional[str] = None,
|
|
69
|
+
model: str = "Meta-Llama-3.1-8B-Instruct",
|
|
70
|
+
system_prompt: str = "You are a helpful AI assistant.",
|
|
71
|
+
):
|
|
72
|
+
"""
|
|
73
|
+
Initializes the Sambanova API with given parameters.
|
|
74
|
+
"""
|
|
75
|
+
self.api_key = api_key
|
|
76
|
+
self.model = model
|
|
77
|
+
self.system_prompt = system_prompt
|
|
78
|
+
self.timeout = timeout
|
|
79
|
+
|
|
80
|
+
# Update models list dynamically if API key is provided
|
|
81
|
+
if api_key:
|
|
82
|
+
self.update_available_models()
|
|
83
|
+
|
|
84
|
+
# Initialize curl_cffi Session
|
|
85
|
+
self.session = Session()
|
|
86
|
+
self.is_conversation = is_conversation
|
|
87
|
+
self.max_tokens_to_sample = max_tokens
|
|
88
|
+
self.last_response = {}
|
|
89
|
+
|
|
90
|
+
self.headers = {
|
|
91
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
92
|
+
"Content-Type": "application/json",
|
|
93
|
+
"User-Agent": Lit().random(),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# Update curl_cffi session headers and proxies
|
|
97
|
+
self.session = Session()
|
|
98
|
+
self.session.headers.update(self.headers)
|
|
99
|
+
if proxies:
|
|
100
|
+
self.session.proxies.update(proxies)
|
|
101
|
+
self.system_prompt = system_prompt
|
|
102
|
+
|
|
103
|
+
self.__available_optimizers = (
|
|
104
|
+
method
|
|
105
|
+
for method in dir(Optimizers)
|
|
106
|
+
if callable(getattr(Optimizers, method)) and not method.startswith("__")
|
|
107
|
+
)
|
|
108
|
+
self.conversation = Conversation(
|
|
109
|
+
is_conversation, self.max_tokens_to_sample, filepath, update_file
|
|
110
|
+
)
|
|
111
|
+
self.conversation.history_offset = history_offset
|
|
112
|
+
|
|
113
|
+
if act:
|
|
114
|
+
self.conversation.intro = AwesomePrompts().get_act(cast(Union[str, int], act), default=self.conversation.intro, case_insensitive=True
|
|
115
|
+
) or self.conversation.intro
|
|
116
|
+
elif intro:
|
|
117
|
+
self.conversation.intro = intro
|
|
118
|
+
|
|
119
|
+
# Configure the API base URL
|
|
120
|
+
self.base_url = "https://api.sambanova.ai/v1/chat/completions"
|
|
121
|
+
|
|
122
|
+
def ask(
|
|
123
|
+
self,
|
|
124
|
+
prompt: str,
|
|
125
|
+
stream: bool = False,
|
|
126
|
+
raw: bool = False,
|
|
127
|
+
optimizer: Optional[str] = None,
|
|
128
|
+
conversationally: bool = False,
|
|
129
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
130
|
+
tool_choice: Optional[Dict[str, Any]] = None,
|
|
131
|
+
**kwargs: Any,
|
|
132
|
+
) -> Response:
|
|
133
|
+
"""Chat with AI using the Sambanova API."""
|
|
134
|
+
conversation_prompt = self.conversation.gen_complete_prompt(prompt)
|
|
135
|
+
if optimizer:
|
|
136
|
+
if optimizer in self.__available_optimizers:
|
|
137
|
+
conversation_prompt = getattr(Optimizers, optimizer)(
|
|
138
|
+
conversation_prompt if conversationally else prompt
|
|
139
|
+
)
|
|
140
|
+
else:
|
|
141
|
+
raise Exception(
|
|
142
|
+
f"Optimizer is not one of {list(self.__available_optimizers)}"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
payload = {
|
|
146
|
+
"model": self.model,
|
|
147
|
+
"messages": [
|
|
148
|
+
{"role": "system", "content": self.system_prompt},
|
|
149
|
+
{"role": "user", "content": conversation_prompt},
|
|
150
|
+
],
|
|
151
|
+
"max_tokens": self.max_tokens_to_sample,
|
|
152
|
+
"stream": stream
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if tools:
|
|
156
|
+
payload["tools"] = tools
|
|
157
|
+
if tool_choice:
|
|
158
|
+
payload["tool_choice"] = tool_choice
|
|
159
|
+
|
|
160
|
+
def for_stream():
|
|
161
|
+
try:
|
|
162
|
+
# Use curl_cffi session post with impersonate
|
|
163
|
+
response = self.session.post(
|
|
164
|
+
self.base_url,
|
|
165
|
+
json=payload,
|
|
166
|
+
stream=True,
|
|
167
|
+
timeout=self.timeout,
|
|
168
|
+
impersonate="chrome120"
|
|
169
|
+
)
|
|
170
|
+
response.raise_for_status()
|
|
171
|
+
|
|
172
|
+
streaming_text = ""
|
|
173
|
+
processed_stream = sanitize_stream(
|
|
174
|
+
data=response.iter_lines(),
|
|
175
|
+
intro_value="data:",
|
|
176
|
+
to_json=True,
|
|
177
|
+
skip_markers=["[DONE]"],
|
|
178
|
+
content_extractor=lambda chunk: chunk.get('choices', [{}])[0].get('delta') if isinstance(chunk, dict) else None,
|
|
179
|
+
yield_raw_on_error=False,
|
|
180
|
+
raw=raw
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
for delta in processed_stream:
|
|
184
|
+
if isinstance(delta, dict):
|
|
185
|
+
if 'content' in delta and delta['content'] is not None:
|
|
186
|
+
content = delta['content']
|
|
187
|
+
if raw:
|
|
188
|
+
yield content
|
|
189
|
+
else:
|
|
190
|
+
streaming_text += content
|
|
191
|
+
yield {"text": content}
|
|
192
|
+
elif 'tool_calls' in delta:
|
|
193
|
+
tool_calls = delta['tool_calls']
|
|
194
|
+
if raw:
|
|
195
|
+
yield json.dumps(tool_calls)
|
|
196
|
+
else:
|
|
197
|
+
yield {"tool_calls": tool_calls}
|
|
198
|
+
|
|
199
|
+
self.last_response.update({"text": streaming_text})
|
|
200
|
+
if streaming_text:
|
|
201
|
+
self.conversation.update_chat_history(prompt, streaming_text)
|
|
202
|
+
|
|
203
|
+
except CurlError as e:
|
|
204
|
+
raise exceptions.ProviderConnectionError(f"Request failed (CurlError): {e}") from e
|
|
205
|
+
except Exception as e:
|
|
206
|
+
raise exceptions.ProviderConnectionError(f"Request failed ({type(e).__name__}): {e}") from e
|
|
207
|
+
|
|
208
|
+
def for_non_stream():
|
|
209
|
+
try:
|
|
210
|
+
payload["stream"] = False
|
|
211
|
+
response = self.session.post(
|
|
212
|
+
self.base_url,
|
|
213
|
+
json=payload,
|
|
214
|
+
timeout=self.timeout,
|
|
215
|
+
impersonate="chrome120"
|
|
216
|
+
)
|
|
217
|
+
response.raise_for_status()
|
|
218
|
+
resp_json = response.json()
|
|
219
|
+
|
|
220
|
+
if 'choices' in resp_json and len(resp_json['choices']) > 0:
|
|
221
|
+
choice = resp_json['choices'][0]
|
|
222
|
+
message = choice.get('message', {})
|
|
223
|
+
content = message.get('content', '')
|
|
224
|
+
tool_calls = message.get('tool_calls')
|
|
225
|
+
|
|
226
|
+
result = {}
|
|
227
|
+
if content:
|
|
228
|
+
result["text"] = content
|
|
229
|
+
if tool_calls:
|
|
230
|
+
result["tool_calls"] = tool_calls
|
|
231
|
+
|
|
232
|
+
self.last_response = result
|
|
233
|
+
self.conversation.update_chat_history(prompt, content or "")
|
|
234
|
+
|
|
235
|
+
if raw:
|
|
236
|
+
return content if content else (json.dumps(tool_calls) if tool_calls else "")
|
|
237
|
+
return result
|
|
238
|
+
else:
|
|
239
|
+
return {}
|
|
240
|
+
|
|
241
|
+
except Exception as e:
|
|
242
|
+
raise exceptions.FailedToGenerateResponseError(f"Non-stream request failed: {e}") from e
|
|
243
|
+
|
|
244
|
+
return for_stream() if stream else for_non_stream()
|
|
245
|
+
|
|
246
|
+
def chat(
|
|
247
|
+
self,
|
|
248
|
+
prompt: str,
|
|
249
|
+
stream: bool = False,
|
|
250
|
+
optimizer: Optional[str] = None,
|
|
251
|
+
conversationally: bool = False,
|
|
252
|
+
**kwargs: Any,
|
|
253
|
+
) -> Union[str, Generator[str, None, None]]:
|
|
254
|
+
"""Generate response `str`"""
|
|
255
|
+
raw = kwargs.get("raw", False)
|
|
256
|
+
tools = kwargs.get("tools")
|
|
257
|
+
tool_choice = kwargs.get("tool_choice")
|
|
258
|
+
|
|
259
|
+
def for_stream_chat():
|
|
260
|
+
# ask() yields dicts or strings when streaming
|
|
261
|
+
gen = self.ask(
|
|
262
|
+
prompt, stream=True, raw=raw,
|
|
263
|
+
optimizer=optimizer, conversationally=conversationally,
|
|
264
|
+
tools=tools, tool_choice=tool_choice
|
|
265
|
+
)
|
|
266
|
+
for response_dict in gen:
|
|
267
|
+
if raw:
|
|
268
|
+
yield cast(str, response_dict)
|
|
269
|
+
else:
|
|
270
|
+
yield self.get_message(cast(Response, response_dict))
|
|
271
|
+
|
|
272
|
+
def for_non_stream_chat():
|
|
273
|
+
# ask() returns dict or str when not streaming
|
|
274
|
+
response_data = self.ask(
|
|
275
|
+
prompt,
|
|
276
|
+
stream=False,
|
|
277
|
+
raw=raw,
|
|
278
|
+
optimizer=optimizer,
|
|
279
|
+
conversationally=conversationally,
|
|
280
|
+
tools=tools,
|
|
281
|
+
tool_choice=tool_choice
|
|
282
|
+
)
|
|
283
|
+
if raw:
|
|
284
|
+
return cast(str, response_data)
|
|
285
|
+
return self.get_message(response_data)
|
|
286
|
+
|
|
287
|
+
return for_stream_chat() if stream else for_non_stream_chat()
|
|
288
|
+
|
|
289
|
+
def get_message(self, response: Response) -> str:
|
|
290
|
+
"""
|
|
291
|
+
Retrieves a clean message from the provided response.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
response: The raw response data.
|
|
295
|
+
|
|
296
|
+
Returns:
|
|
297
|
+
str: The extracted message.
|
|
298
|
+
"""
|
|
299
|
+
if isinstance(response, str):
|
|
300
|
+
return response
|
|
301
|
+
elif isinstance(response, dict):
|
|
302
|
+
if "text" in response:
|
|
303
|
+
return response["text"]
|
|
304
|
+
elif "tool_calls" in response:
|
|
305
|
+
return json.dumps(response["tool_calls"])
|
|
306
|
+
return str(response)
|
|
307
|
+
|
|
308
|
+
if __name__ == "__main__":
|
|
309
|
+
# Ensure curl_cffi is installed
|
|
310
|
+
from rich import print
|
|
311
|
+
ai = Sambanova(api_key='')
|
|
312
|
+
response = ai.chat(input(">>> "), stream=True)
|
|
313
|
+
if hasattr(response, "__iter__") and not isinstance(response, (str, bytes)):
|
|
314
|
+
for chunk in response:
|
|
315
|
+
print(chunk, end="", flush=True)
|
|
316
|
+
else:
|
|
317
|
+
print(response)
|
webscout/Provider/TTI/README.md
CHANGED
|
@@ -1,82 +1,69 @@
|
|
|
1
|
-
# 🖼️ Webscout Text-to-Image (TTI) Providers
|
|
2
|
-
|
|
3
|
-
Webscout includes a collection of Text-to-Image providers that follow a common interface inspired by the OpenAI Python client. Each provider exposes an `images.create()` method which returns an `ImageResponse` object containing either image URLs or base64 data.
|
|
4
|
-
|
|
5
|
-
These providers allow you to easily generate AI‑created art from text prompts while handling image conversion and temporary hosting automatically.
|
|
6
|
-
|
|
7
|
-
## ✨ Features
|
|
8
|
-
|
|
9
|
-
- **Unified API** – Consistent `images.create()` method for all providers
|
|
10
|
-
- **Multiple Providers** – Generate images using different third‑party services
|
|
11
|
-
- **URL or Base64 Output** – Receive image URLs (uploaded to catbox.moe/0x0.st) or base64 encoded bytes
|
|
12
|
-
- **PNG/JPEG Conversion** – Images are converted in memory to your chosen format
|
|
13
|
-
- **Model Listing** – Query available models with `provider.models.list()`
|
|
14
|
-
|
|
15
|
-
## 📦 Supported Providers
|
|
16
|
-
|
|
17
|
-
| Provider
|
|
18
|
-
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
> **Note**: Some providers require the `Pillow` package for image processing.
|
|
27
|
-
|
|
28
|
-
## 🚀 Quick Start
|
|
29
|
-
|
|
30
|
-
```python
|
|
31
|
-
from webscout.Provider.TTI import
|
|
32
|
-
|
|
33
|
-
# Initialize the provider
|
|
34
|
-
client =
|
|
35
|
-
|
|
36
|
-
# Generate two images and get URLs
|
|
37
|
-
response = client.images.create(
|
|
38
|
-
model="flux
|
|
39
|
-
prompt="A futuristic city skyline at sunset",
|
|
40
|
-
n=2,
|
|
41
|
-
response_format="url"
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
print(response)
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
###
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```python
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
## 🔧 Provider Specifics
|
|
72
|
-
|
|
73
|
-
- **AIArta** – Uses Firebase authentication tokens and supports many tattoo‑style models.
|
|
74
|
-
- **FastFluxAI** – Simple API for quick image generation.
|
|
75
|
-
- **MagicStudioAI** – Generates images through MagicStudio's public endpoint.
|
|
76
|
-
- **PixelMuse** – Supports several models and converts images from WebP.
|
|
77
|
-
- **PiclumenAI** – Returns JPEG images directly from the API.
|
|
78
|
-
- **PollinationsAI** – Allows setting a custom seed for reproducible results.
|
|
79
|
-
|
|
80
|
-
## 🤝 Contributing
|
|
81
|
-
|
|
82
|
-
Contributions and additional providers are welcome! Feel free to submit a pull request.
|
|
1
|
+
# 🖼️ Webscout Text-to-Image (TTI) Providers
|
|
2
|
+
|
|
3
|
+
Webscout includes a collection of Text-to-Image providers that follow a common interface inspired by the OpenAI Python client. Each provider exposes an `images.create()` method which returns an `ImageResponse` object containing either image URLs or base64 data.
|
|
4
|
+
|
|
5
|
+
These providers allow you to easily generate AI‑created art from text prompts while handling image conversion and temporary hosting automatically.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- **Unified API** – Consistent `images.create()` method for all providers
|
|
10
|
+
- **Multiple Providers** – Generate images using different third‑party services
|
|
11
|
+
- **URL or Base64 Output** – Receive image URLs (uploaded to catbox.moe/0x0.st) or base64 encoded bytes
|
|
12
|
+
- **PNG/JPEG Conversion** – Images are converted in memory to your chosen format
|
|
13
|
+
- **Model Listing** – Query available models with `provider.models.list()`
|
|
14
|
+
|
|
15
|
+
## 📦 Supported Providers
|
|
16
|
+
|
|
17
|
+
| Provider | Available Models (examples) | Status |
|
|
18
|
+
| ---------------- | ----------------------------------------- | --------- |
|
|
19
|
+
| `PollinationsAI` | `flux`, `flux-pro`, `turbo`, `gptimage` | Working |
|
|
20
|
+
| `MagicStudioAI` | `magicstudio` | Working |
|
|
21
|
+
| `ClaudeOnlineTTI`| `claude-imagine` | Working |
|
|
22
|
+
| `TogetherImage` | `flux.1-schnell`, `flux.1-pro` | Working* |
|
|
23
|
+
|
|
24
|
+
\* Requires authentication (API keys).
|
|
25
|
+
|
|
26
|
+
> **Note**: Some providers require the `Pillow` package for image processing.
|
|
27
|
+
|
|
28
|
+
## 🚀 Quick Start
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from webscout.Provider.TTI import PollinationsAI
|
|
32
|
+
|
|
33
|
+
# Initialize the provider
|
|
34
|
+
client = PollinationsAI()
|
|
35
|
+
|
|
36
|
+
# Generate two images and get URLs
|
|
37
|
+
response = client.images.create(
|
|
38
|
+
model="flux",
|
|
39
|
+
prompt="A futuristic city skyline at sunset",
|
|
40
|
+
n=2,
|
|
41
|
+
response_format="url"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
print(response)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Base64 Output
|
|
48
|
+
|
|
49
|
+
If you prefer the raw image data:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
response = client.images.create(
|
|
53
|
+
model="flux",
|
|
54
|
+
prompt="Crystal mountain landscape",
|
|
55
|
+
response_format="b64_json"
|
|
56
|
+
)
|
|
57
|
+
# `response.data` will contain base64 strings
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 🔧 Provider Specifics
|
|
61
|
+
|
|
62
|
+
- **PollinationsAI** – Allows setting a custom seed for reproducible results.
|
|
63
|
+
- **MagicStudioAI** – Generates images through MagicStudio's public endpoint.
|
|
64
|
+
- **ClaudeOnlineTTI** – Uses Pollinations.ai backend to provide image generation capabilities.
|
|
65
|
+
- **TogetherImage** – High-quality image generation via Together.xyz API (Requires API Key).
|
|
66
|
+
|
|
67
|
+
## 🤝 Contributing
|
|
68
|
+
|
|
69
|
+
Contributions and additional providers are welcome! Feel free to submit a pull request.
|
|
@@ -1,7 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from .
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
# This file marks the directory as a Python package.
|
|
2
|
+
# Static imports for all TTI (Text-to-Image) provider modules
|
|
3
|
+
|
|
4
|
+
# Base classes
|
|
5
|
+
from webscout.Provider.TTI.base import (
|
|
6
|
+
BaseImages,
|
|
7
|
+
TTICompatibleProvider,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
# Provider implementations
|
|
11
|
+
from webscout.Provider.TTI.claudeonline import ClaudeOnlineTTI
|
|
12
|
+
from webscout.Provider.TTI.magicstudio import MagicStudioAI
|
|
13
|
+
from webscout.Provider.TTI.miragic import MiragicAI
|
|
14
|
+
from webscout.Provider.TTI.pollinations import PollinationsAI
|
|
15
|
+
from webscout.Provider.TTI.together import TogetherImage
|
|
16
|
+
|
|
17
|
+
# Utility classes
|
|
18
|
+
from webscout.Provider.TTI.utils import (
|
|
19
|
+
ImageData,
|
|
20
|
+
ImageResponse,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# List of all exported names
|
|
24
|
+
__all__ = [
|
|
25
|
+
# Base classes
|
|
26
|
+
"TTICompatibleProvider",
|
|
27
|
+
"BaseImages",
|
|
28
|
+
# Utilities
|
|
29
|
+
"ImageData",
|
|
30
|
+
"ImageResponse",
|
|
31
|
+
# Providers
|
|
32
|
+
"ClaudeOnlineTTI",
|
|
33
|
+
"MagicStudioAI",
|
|
34
|
+
"PollinationsAI",
|
|
35
|
+
"TogetherImage",
|
|
36
|
+
"MiragicAI",
|
|
37
|
+
]
|