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.
Files changed (483) hide show
  1. webscout/AIauto.py +524 -143
  2. webscout/AIbase.py +247 -123
  3. webscout/AIutel.py +68 -132
  4. webscout/Bard.py +1072 -535
  5. webscout/Extra/GitToolkit/__init__.py +2 -2
  6. webscout/Extra/GitToolkit/gitapi/__init__.py +20 -12
  7. webscout/Extra/GitToolkit/gitapi/gist.py +142 -0
  8. webscout/Extra/GitToolkit/gitapi/organization.py +91 -0
  9. webscout/Extra/GitToolkit/gitapi/repository.py +308 -195
  10. webscout/Extra/GitToolkit/gitapi/search.py +162 -0
  11. webscout/Extra/GitToolkit/gitapi/trending.py +236 -0
  12. webscout/Extra/GitToolkit/gitapi/user.py +128 -96
  13. webscout/Extra/GitToolkit/gitapi/utils.py +82 -62
  14. webscout/Extra/YTToolkit/README.md +443 -0
  15. webscout/Extra/YTToolkit/YTdownloader.py +953 -957
  16. webscout/Extra/YTToolkit/__init__.py +3 -3
  17. webscout/Extra/YTToolkit/transcriber.py +595 -476
  18. webscout/Extra/YTToolkit/ytapi/README.md +230 -0
  19. webscout/Extra/YTToolkit/ytapi/__init__.py +22 -6
  20. webscout/Extra/YTToolkit/ytapi/captions.py +190 -0
  21. webscout/Extra/YTToolkit/ytapi/channel.py +302 -307
  22. webscout/Extra/YTToolkit/ytapi/errors.py +13 -13
  23. webscout/Extra/YTToolkit/ytapi/extras.py +178 -45
  24. webscout/Extra/YTToolkit/ytapi/hashtag.py +120 -0
  25. webscout/Extra/YTToolkit/ytapi/https.py +89 -88
  26. webscout/Extra/YTToolkit/ytapi/patterns.py +61 -61
  27. webscout/Extra/YTToolkit/ytapi/playlist.py +59 -59
  28. webscout/Extra/YTToolkit/ytapi/pool.py +8 -8
  29. webscout/Extra/YTToolkit/ytapi/query.py +143 -40
  30. webscout/Extra/YTToolkit/ytapi/shorts.py +122 -0
  31. webscout/Extra/YTToolkit/ytapi/stream.py +68 -63
  32. webscout/Extra/YTToolkit/ytapi/suggestions.py +97 -0
  33. webscout/Extra/YTToolkit/ytapi/utils.py +66 -62
  34. webscout/Extra/YTToolkit/ytapi/video.py +189 -18
  35. webscout/Extra/__init__.py +2 -3
  36. webscout/Extra/gguf.py +1298 -682
  37. webscout/Extra/tempmail/README.md +488 -0
  38. webscout/Extra/tempmail/__init__.py +28 -28
  39. webscout/Extra/tempmail/async_utils.py +143 -141
  40. webscout/Extra/tempmail/base.py +172 -161
  41. webscout/Extra/tempmail/cli.py +191 -187
  42. webscout/Extra/tempmail/emailnator.py +88 -84
  43. webscout/Extra/tempmail/mail_tm.py +378 -361
  44. webscout/Extra/tempmail/temp_mail_io.py +304 -292
  45. webscout/Extra/weather.py +196 -194
  46. webscout/Extra/weather_ascii.py +17 -15
  47. webscout/Provider/AISEARCH/PERPLEXED_search.py +175 -0
  48. webscout/Provider/AISEARCH/Perplexity.py +237 -304
  49. webscout/Provider/AISEARCH/README.md +106 -0
  50. webscout/Provider/AISEARCH/__init__.py +16 -10
  51. webscout/Provider/AISEARCH/brave_search.py +298 -0
  52. webscout/Provider/AISEARCH/iask_search.py +130 -209
  53. webscout/Provider/AISEARCH/monica_search.py +200 -246
  54. webscout/Provider/AISEARCH/webpilotai_search.py +242 -281
  55. webscout/Provider/Algion.py +413 -0
  56. webscout/Provider/Andi.py +74 -69
  57. webscout/Provider/Apriel.py +313 -0
  58. webscout/Provider/Ayle.py +323 -0
  59. webscout/Provider/ChatSandbox.py +329 -0
  60. webscout/Provider/ClaudeOnline.py +365 -0
  61. webscout/Provider/Cohere.py +232 -208
  62. webscout/Provider/DeepAI.py +367 -0
  63. webscout/Provider/Deepinfra.py +343 -173
  64. webscout/Provider/EssentialAI.py +217 -0
  65. webscout/Provider/ExaAI.py +274 -261
  66. webscout/Provider/Gemini.py +60 -54
  67. webscout/Provider/GithubChat.py +385 -367
  68. webscout/Provider/Gradient.py +286 -0
  69. webscout/Provider/Groq.py +556 -670
  70. webscout/Provider/HadadXYZ.py +323 -0
  71. webscout/Provider/HeckAI.py +392 -233
  72. webscout/Provider/HuggingFace.py +387 -0
  73. webscout/Provider/IBM.py +340 -0
  74. webscout/Provider/Jadve.py +317 -266
  75. webscout/Provider/K2Think.py +306 -0
  76. webscout/Provider/Koboldai.py +221 -381
  77. webscout/Provider/Netwrck.py +273 -228
  78. webscout/Provider/Nvidia.py +310 -0
  79. webscout/Provider/OPENAI/DeepAI.py +489 -0
  80. webscout/Provider/OPENAI/K2Think.py +423 -0
  81. webscout/Provider/OPENAI/PI.py +463 -0
  82. webscout/Provider/OPENAI/README.md +890 -0
  83. webscout/Provider/OPENAI/TogetherAI.py +405 -0
  84. webscout/Provider/OPENAI/TwoAI.py +255 -0
  85. webscout/Provider/OPENAI/__init__.py +148 -25
  86. webscout/Provider/OPENAI/ai4chat.py +348 -0
  87. webscout/Provider/OPENAI/akashgpt.py +436 -0
  88. webscout/Provider/OPENAI/algion.py +303 -0
  89. webscout/Provider/OPENAI/ayle.py +365 -0
  90. webscout/Provider/OPENAI/base.py +253 -46
  91. webscout/Provider/OPENAI/cerebras.py +296 -0
  92. webscout/Provider/OPENAI/chatgpt.py +514 -193
  93. webscout/Provider/OPENAI/chatsandbox.py +233 -0
  94. webscout/Provider/OPENAI/deepinfra.py +403 -272
  95. webscout/Provider/OPENAI/e2b.py +2370 -1350
  96. webscout/Provider/OPENAI/elmo.py +278 -0
  97. webscout/Provider/OPENAI/exaai.py +186 -138
  98. webscout/Provider/OPENAI/freeassist.py +446 -0
  99. webscout/Provider/OPENAI/gradient.py +448 -0
  100. webscout/Provider/OPENAI/groq.py +380 -0
  101. webscout/Provider/OPENAI/hadadxyz.py +292 -0
  102. webscout/Provider/OPENAI/heckai.py +100 -104
  103. webscout/Provider/OPENAI/huggingface.py +321 -0
  104. webscout/Provider/OPENAI/ibm.py +425 -0
  105. webscout/Provider/OPENAI/llmchat.py +253 -0
  106. webscout/Provider/OPENAI/llmchatco.py +378 -327
  107. webscout/Provider/OPENAI/meta.py +541 -0
  108. webscout/Provider/OPENAI/netwrck.py +110 -84
  109. webscout/Provider/OPENAI/nvidia.py +317 -0
  110. webscout/Provider/OPENAI/oivscode.py +348 -0
  111. webscout/Provider/OPENAI/openrouter.py +328 -0
  112. webscout/Provider/OPENAI/pydantic_imports.py +1 -0
  113. webscout/Provider/OPENAI/sambanova.py +397 -0
  114. webscout/Provider/OPENAI/sonus.py +126 -115
  115. webscout/Provider/OPENAI/textpollinations.py +218 -133
  116. webscout/Provider/OPENAI/toolbaz.py +136 -166
  117. webscout/Provider/OPENAI/typefully.py +419 -0
  118. webscout/Provider/OPENAI/typliai.py +279 -0
  119. webscout/Provider/OPENAI/utils.py +314 -211
  120. webscout/Provider/OPENAI/wisecat.py +103 -125
  121. webscout/Provider/OPENAI/writecream.py +185 -156
  122. webscout/Provider/OPENAI/x0gpt.py +227 -136
  123. webscout/Provider/OPENAI/zenmux.py +380 -0
  124. webscout/Provider/OpenRouter.py +386 -0
  125. webscout/Provider/Openai.py +337 -496
  126. webscout/Provider/PI.py +443 -344
  127. webscout/Provider/QwenLM.py +346 -254
  128. webscout/Provider/STT/__init__.py +28 -0
  129. webscout/Provider/STT/base.py +303 -0
  130. webscout/Provider/STT/elevenlabs.py +264 -0
  131. webscout/Provider/Sambanova.py +317 -0
  132. webscout/Provider/TTI/README.md +69 -0
  133. webscout/Provider/TTI/__init__.py +37 -12
  134. webscout/Provider/TTI/base.py +147 -0
  135. webscout/Provider/TTI/claudeonline.py +393 -0
  136. webscout/Provider/TTI/magicstudio.py +292 -0
  137. webscout/Provider/TTI/miragic.py +180 -0
  138. webscout/Provider/TTI/pollinations.py +331 -0
  139. webscout/Provider/TTI/together.py +334 -0
  140. webscout/Provider/TTI/utils.py +14 -0
  141. webscout/Provider/TTS/README.md +186 -0
  142. webscout/Provider/TTS/__init__.py +43 -7
  143. webscout/Provider/TTS/base.py +523 -0
  144. webscout/Provider/TTS/deepgram.py +286 -156
  145. webscout/Provider/TTS/elevenlabs.py +189 -111
  146. webscout/Provider/TTS/freetts.py +218 -0
  147. webscout/Provider/TTS/murfai.py +288 -113
  148. webscout/Provider/TTS/openai_fm.py +364 -0
  149. webscout/Provider/TTS/parler.py +203 -111
  150. webscout/Provider/TTS/qwen.py +334 -0
  151. webscout/Provider/TTS/sherpa.py +286 -0
  152. webscout/Provider/TTS/speechma.py +693 -180
  153. webscout/Provider/TTS/streamElements.py +275 -333
  154. webscout/Provider/TTS/utils.py +280 -280
  155. webscout/Provider/TextPollinationsAI.py +221 -121
  156. webscout/Provider/TogetherAI.py +450 -0
  157. webscout/Provider/TwoAI.py +309 -199
  158. webscout/Provider/TypliAI.py +311 -0
  159. webscout/Provider/UNFINISHED/ChatHub.py +219 -0
  160. webscout/Provider/{OPENAI/glider.py → UNFINISHED/ChutesAI.py} +160 -145
  161. webscout/Provider/UNFINISHED/GizAI.py +300 -0
  162. webscout/Provider/UNFINISHED/Marcus.py +218 -0
  163. webscout/Provider/UNFINISHED/Qodo.py +481 -0
  164. webscout/Provider/UNFINISHED/XenAI.py +330 -0
  165. webscout/Provider/{Youchat.py → UNFINISHED/Youchat.py} +64 -47
  166. webscout/Provider/UNFINISHED/aihumanizer.py +41 -0
  167. webscout/Provider/UNFINISHED/grammerchecker.py +37 -0
  168. webscout/Provider/UNFINISHED/liner.py +342 -0
  169. webscout/Provider/UNFINISHED/liner_api_request.py +246 -0
  170. webscout/Provider/UNFINISHED/samurai.py +231 -0
  171. webscout/Provider/WiseCat.py +256 -196
  172. webscout/Provider/WrDoChat.py +390 -0
  173. webscout/Provider/__init__.py +115 -198
  174. webscout/Provider/ai4chat.py +181 -202
  175. webscout/Provider/akashgpt.py +330 -342
  176. webscout/Provider/cerebras.py +397 -242
  177. webscout/Provider/cleeai.py +236 -213
  178. webscout/Provider/elmo.py +291 -234
  179. webscout/Provider/geminiapi.py +343 -208
  180. webscout/Provider/julius.py +245 -223
  181. webscout/Provider/learnfastai.py +333 -266
  182. webscout/Provider/llama3mitril.py +230 -180
  183. webscout/Provider/llmchat.py +308 -213
  184. webscout/Provider/llmchatco.py +321 -311
  185. webscout/Provider/meta.py +996 -794
  186. webscout/Provider/oivscode.py +332 -0
  187. webscout/Provider/searchchat.py +316 -293
  188. webscout/Provider/sonus.py +264 -208
  189. webscout/Provider/toolbaz.py +359 -320
  190. webscout/Provider/turboseek.py +332 -219
  191. webscout/Provider/typefully.py +262 -280
  192. webscout/Provider/x0gpt.py +332 -256
  193. webscout/__init__.py +31 -38
  194. webscout/__main__.py +5 -5
  195. webscout/cli.py +585 -293
  196. webscout/client.py +1497 -0
  197. webscout/conversation.py +140 -565
  198. webscout/exceptions.py +383 -339
  199. webscout/litagent/__init__.py +29 -29
  200. webscout/litagent/agent.py +492 -455
  201. webscout/litagent/constants.py +60 -60
  202. webscout/models.py +505 -181
  203. webscout/optimizers.py +32 -378
  204. webscout/prompt_manager.py +376 -274
  205. webscout/sanitize.py +1514 -0
  206. webscout/scout/README.md +452 -0
  207. webscout/scout/__init__.py +8 -8
  208. webscout/scout/core/__init__.py +7 -7
  209. webscout/scout/core/crawler.py +330 -140
  210. webscout/scout/core/scout.py +800 -568
  211. webscout/scout/core/search_result.py +51 -96
  212. webscout/scout/core/text_analyzer.py +64 -63
  213. webscout/scout/core/text_utils.py +412 -277
  214. webscout/scout/core/web_analyzer.py +54 -52
  215. webscout/scout/element.py +872 -460
  216. webscout/scout/parsers/__init__.py +70 -69
  217. webscout/scout/parsers/html5lib_parser.py +182 -172
  218. webscout/scout/parsers/html_parser.py +238 -236
  219. webscout/scout/parsers/lxml_parser.py +203 -178
  220. webscout/scout/utils.py +38 -37
  221. webscout/search/__init__.py +47 -0
  222. webscout/search/base.py +201 -0
  223. webscout/search/bing_main.py +45 -0
  224. webscout/search/brave_main.py +92 -0
  225. webscout/search/duckduckgo_main.py +57 -0
  226. webscout/search/engines/__init__.py +127 -0
  227. webscout/search/engines/bing/__init__.py +15 -0
  228. webscout/search/engines/bing/base.py +35 -0
  229. webscout/search/engines/bing/images.py +114 -0
  230. webscout/search/engines/bing/news.py +96 -0
  231. webscout/search/engines/bing/suggestions.py +36 -0
  232. webscout/search/engines/bing/text.py +109 -0
  233. webscout/search/engines/brave/__init__.py +19 -0
  234. webscout/search/engines/brave/base.py +47 -0
  235. webscout/search/engines/brave/images.py +213 -0
  236. webscout/search/engines/brave/news.py +353 -0
  237. webscout/search/engines/brave/suggestions.py +318 -0
  238. webscout/search/engines/brave/text.py +167 -0
  239. webscout/search/engines/brave/videos.py +364 -0
  240. webscout/search/engines/duckduckgo/__init__.py +25 -0
  241. webscout/search/engines/duckduckgo/answers.py +80 -0
  242. webscout/search/engines/duckduckgo/base.py +189 -0
  243. webscout/search/engines/duckduckgo/images.py +100 -0
  244. webscout/search/engines/duckduckgo/maps.py +183 -0
  245. webscout/search/engines/duckduckgo/news.py +70 -0
  246. webscout/search/engines/duckduckgo/suggestions.py +22 -0
  247. webscout/search/engines/duckduckgo/text.py +221 -0
  248. webscout/search/engines/duckduckgo/translate.py +48 -0
  249. webscout/search/engines/duckduckgo/videos.py +80 -0
  250. webscout/search/engines/duckduckgo/weather.py +84 -0
  251. webscout/search/engines/mojeek.py +61 -0
  252. webscout/search/engines/wikipedia.py +77 -0
  253. webscout/search/engines/yahoo/__init__.py +41 -0
  254. webscout/search/engines/yahoo/answers.py +19 -0
  255. webscout/search/engines/yahoo/base.py +34 -0
  256. webscout/search/engines/yahoo/images.py +323 -0
  257. webscout/search/engines/yahoo/maps.py +19 -0
  258. webscout/search/engines/yahoo/news.py +258 -0
  259. webscout/search/engines/yahoo/suggestions.py +140 -0
  260. webscout/search/engines/yahoo/text.py +273 -0
  261. webscout/search/engines/yahoo/translate.py +19 -0
  262. webscout/search/engines/yahoo/videos.py +302 -0
  263. webscout/search/engines/yahoo/weather.py +220 -0
  264. webscout/search/engines/yandex.py +67 -0
  265. webscout/search/engines/yep/__init__.py +13 -0
  266. webscout/search/engines/yep/base.py +34 -0
  267. webscout/search/engines/yep/images.py +101 -0
  268. webscout/search/engines/yep/suggestions.py +38 -0
  269. webscout/search/engines/yep/text.py +99 -0
  270. webscout/search/http_client.py +172 -0
  271. webscout/search/results.py +141 -0
  272. webscout/search/yahoo_main.py +57 -0
  273. webscout/search/yep_main.py +48 -0
  274. webscout/server/__init__.py +48 -0
  275. webscout/server/config.py +78 -0
  276. webscout/server/exceptions.py +69 -0
  277. webscout/server/providers.py +286 -0
  278. webscout/server/request_models.py +131 -0
  279. webscout/server/request_processing.py +404 -0
  280. webscout/server/routes.py +642 -0
  281. webscout/server/server.py +351 -0
  282. webscout/server/ui_templates.py +1171 -0
  283. webscout/swiftcli/__init__.py +79 -809
  284. webscout/swiftcli/core/__init__.py +7 -0
  285. webscout/swiftcli/core/cli.py +574 -0
  286. webscout/swiftcli/core/context.py +98 -0
  287. webscout/swiftcli/core/group.py +268 -0
  288. webscout/swiftcli/decorators/__init__.py +28 -0
  289. webscout/swiftcli/decorators/command.py +243 -0
  290. webscout/swiftcli/decorators/options.py +247 -0
  291. webscout/swiftcli/decorators/output.py +392 -0
  292. webscout/swiftcli/exceptions.py +21 -0
  293. webscout/swiftcli/plugins/__init__.py +9 -0
  294. webscout/swiftcli/plugins/base.py +134 -0
  295. webscout/swiftcli/plugins/manager.py +269 -0
  296. webscout/swiftcli/utils/__init__.py +58 -0
  297. webscout/swiftcli/utils/formatting.py +251 -0
  298. webscout/swiftcli/utils/parsing.py +368 -0
  299. webscout/update_checker.py +280 -136
  300. webscout/utils.py +28 -14
  301. webscout/version.py +2 -1
  302. webscout/version.py.bak +3 -0
  303. webscout/zeroart/__init__.py +218 -55
  304. webscout/zeroart/base.py +70 -60
  305. webscout/zeroart/effects.py +155 -99
  306. webscout/zeroart/fonts.py +1799 -816
  307. webscout-2026.1.19.dist-info/METADATA +638 -0
  308. webscout-2026.1.19.dist-info/RECORD +312 -0
  309. {webscout-8.2.2.dist-info → webscout-2026.1.19.dist-info}/WHEEL +1 -1
  310. webscout-2026.1.19.dist-info/entry_points.txt +4 -0
  311. webscout-2026.1.19.dist-info/top_level.txt +1 -0
  312. inferno/__init__.py +0 -6
  313. inferno/__main__.py +0 -9
  314. inferno/cli.py +0 -6
  315. webscout/DWEBS.py +0 -477
  316. webscout/Extra/autocoder/__init__.py +0 -9
  317. webscout/Extra/autocoder/autocoder.py +0 -849
  318. webscout/Extra/autocoder/autocoder_utiles.py +0 -332
  319. webscout/LLM.py +0 -442
  320. webscout/Litlogger/__init__.py +0 -67
  321. webscout/Litlogger/core/__init__.py +0 -6
  322. webscout/Litlogger/core/level.py +0 -23
  323. webscout/Litlogger/core/logger.py +0 -165
  324. webscout/Litlogger/handlers/__init__.py +0 -12
  325. webscout/Litlogger/handlers/console.py +0 -33
  326. webscout/Litlogger/handlers/file.py +0 -143
  327. webscout/Litlogger/handlers/network.py +0 -173
  328. webscout/Litlogger/styles/__init__.py +0 -7
  329. webscout/Litlogger/styles/colors.py +0 -249
  330. webscout/Litlogger/styles/formats.py +0 -458
  331. webscout/Litlogger/styles/text.py +0 -87
  332. webscout/Litlogger/utils/__init__.py +0 -6
  333. webscout/Litlogger/utils/detectors.py +0 -153
  334. webscout/Litlogger/utils/formatters.py +0 -200
  335. webscout/Local/__init__.py +0 -12
  336. webscout/Local/__main__.py +0 -9
  337. webscout/Local/api.py +0 -576
  338. webscout/Local/cli.py +0 -516
  339. webscout/Local/config.py +0 -75
  340. webscout/Local/llm.py +0 -287
  341. webscout/Local/model_manager.py +0 -253
  342. webscout/Local/server.py +0 -721
  343. webscout/Local/utils.py +0 -93
  344. webscout/Provider/AI21.py +0 -177
  345. webscout/Provider/AISEARCH/DeepFind.py +0 -250
  346. webscout/Provider/AISEARCH/ISou.py +0 -256
  347. webscout/Provider/AISEARCH/felo_search.py +0 -228
  348. webscout/Provider/AISEARCH/genspark_search.py +0 -208
  349. webscout/Provider/AISEARCH/hika_search.py +0 -194
  350. webscout/Provider/AISEARCH/scira_search.py +0 -324
  351. webscout/Provider/Aitopia.py +0 -292
  352. webscout/Provider/AllenAI.py +0 -413
  353. webscout/Provider/Blackboxai.py +0 -229
  354. webscout/Provider/C4ai.py +0 -432
  355. webscout/Provider/ChatGPTClone.py +0 -226
  356. webscout/Provider/ChatGPTES.py +0 -237
  357. webscout/Provider/ChatGPTGratis.py +0 -194
  358. webscout/Provider/Chatify.py +0 -175
  359. webscout/Provider/Cloudflare.py +0 -273
  360. webscout/Provider/DeepSeek.py +0 -196
  361. webscout/Provider/ElectronHub.py +0 -709
  362. webscout/Provider/ExaChat.py +0 -342
  363. webscout/Provider/Free2GPT.py +0 -241
  364. webscout/Provider/GPTWeb.py +0 -193
  365. webscout/Provider/Glider.py +0 -211
  366. webscout/Provider/HF_space/__init__.py +0 -0
  367. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  368. webscout/Provider/HuggingFaceChat.py +0 -462
  369. webscout/Provider/Hunyuan.py +0 -272
  370. webscout/Provider/LambdaChat.py +0 -392
  371. webscout/Provider/Llama.py +0 -200
  372. webscout/Provider/Llama3.py +0 -204
  373. webscout/Provider/Marcus.py +0 -148
  374. webscout/Provider/OLLAMA.py +0 -396
  375. webscout/Provider/OPENAI/c4ai.py +0 -367
  376. webscout/Provider/OPENAI/chatgptclone.py +0 -460
  377. webscout/Provider/OPENAI/exachat.py +0 -433
  378. webscout/Provider/OPENAI/freeaichat.py +0 -352
  379. webscout/Provider/OPENAI/opkfc.py +0 -488
  380. webscout/Provider/OPENAI/scirachat.py +0 -463
  381. webscout/Provider/OPENAI/standardinput.py +0 -425
  382. webscout/Provider/OPENAI/typegpt.py +0 -346
  383. webscout/Provider/OPENAI/uncovrAI.py +0 -455
  384. webscout/Provider/OPENAI/venice.py +0 -413
  385. webscout/Provider/OPENAI/yep.py +0 -327
  386. webscout/Provider/OpenGPT.py +0 -199
  387. webscout/Provider/Perplexitylabs.py +0 -415
  388. webscout/Provider/Phind.py +0 -535
  389. webscout/Provider/PizzaGPT.py +0 -198
  390. webscout/Provider/Reka.py +0 -214
  391. webscout/Provider/StandardInput.py +0 -278
  392. webscout/Provider/TTI/AiForce/__init__.py +0 -22
  393. webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
  394. webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
  395. webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
  396. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
  397. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
  398. webscout/Provider/TTI/ImgSys/__init__.py +0 -23
  399. webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
  400. webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
  401. webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
  402. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
  403. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
  404. webscout/Provider/TTI/Nexra/__init__.py +0 -22
  405. webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
  406. webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
  407. webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
  408. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
  409. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
  410. webscout/Provider/TTI/aiarta/__init__.py +0 -2
  411. webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
  412. webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
  413. webscout/Provider/TTI/artbit/__init__.py +0 -22
  414. webscout/Provider/TTI/artbit/async_artbit.py +0 -155
  415. webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
  416. webscout/Provider/TTI/fastflux/__init__.py +0 -22
  417. webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
  418. webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
  419. webscout/Provider/TTI/huggingface/__init__.py +0 -22
  420. webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
  421. webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
  422. webscout/Provider/TTI/piclumen/__init__.py +0 -23
  423. webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
  424. webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
  425. webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
  426. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
  427. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
  428. webscout/Provider/TTI/talkai/__init__.py +0 -4
  429. webscout/Provider/TTI/talkai/async_talkai.py +0 -229
  430. webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
  431. webscout/Provider/TTS/gesserit.py +0 -127
  432. webscout/Provider/TeachAnything.py +0 -187
  433. webscout/Provider/Venice.py +0 -219
  434. webscout/Provider/VercelAI.py +0 -234
  435. webscout/Provider/WebSim.py +0 -228
  436. webscout/Provider/Writecream.py +0 -211
  437. webscout/Provider/WritingMate.py +0 -197
  438. webscout/Provider/aimathgpt.py +0 -189
  439. webscout/Provider/askmyai.py +0 -158
  440. webscout/Provider/asksteve.py +0 -203
  441. webscout/Provider/bagoodex.py +0 -145
  442. webscout/Provider/chatglm.py +0 -205
  443. webscout/Provider/copilot.py +0 -428
  444. webscout/Provider/freeaichat.py +0 -271
  445. webscout/Provider/gaurish.py +0 -244
  446. webscout/Provider/geminiprorealtime.py +0 -160
  447. webscout/Provider/granite.py +0 -187
  448. webscout/Provider/hermes.py +0 -219
  449. webscout/Provider/koala.py +0 -268
  450. webscout/Provider/labyrinth.py +0 -340
  451. webscout/Provider/lepton.py +0 -194
  452. webscout/Provider/llamatutor.py +0 -192
  453. webscout/Provider/multichat.py +0 -325
  454. webscout/Provider/promptrefine.py +0 -193
  455. webscout/Provider/scira_chat.py +0 -277
  456. webscout/Provider/scnet.py +0 -187
  457. webscout/Provider/talkai.py +0 -194
  458. webscout/Provider/tutorai.py +0 -252
  459. webscout/Provider/typegpt.py +0 -232
  460. webscout/Provider/uncovr.py +0 -312
  461. webscout/Provider/yep.py +0 -376
  462. webscout/litprinter/__init__.py +0 -59
  463. webscout/scout/core.py +0 -881
  464. webscout/tempid.py +0 -128
  465. webscout/webscout_search.py +0 -1346
  466. webscout/webscout_search_async.py +0 -877
  467. webscout/yep_search.py +0 -297
  468. webscout-8.2.2.dist-info/METADATA +0 -734
  469. webscout-8.2.2.dist-info/RECORD +0 -309
  470. webscout-8.2.2.dist-info/entry_points.txt +0 -5
  471. webscout-8.2.2.dist-info/top_level.txt +0 -3
  472. webstoken/__init__.py +0 -30
  473. webstoken/classifier.py +0 -189
  474. webstoken/keywords.py +0 -216
  475. webstoken/language.py +0 -128
  476. webstoken/ner.py +0 -164
  477. webstoken/normalizer.py +0 -35
  478. webstoken/processor.py +0 -77
  479. webstoken/sentiment.py +0 -206
  480. webstoken/stemmer.py +0 -73
  481. webstoken/tagger.py +0 -60
  482. webstoken/tokenizer.py +0 -158
  483. {webscout-8.2.2.dist-info → webscout-2026.1.19.dist-info/licenses}/LICENSE.md +0 -0
@@ -1,22 +1,30 @@
1
+ import json
2
+ import re
1
3
  import time
2
4
  import uuid
5
+ from typing import Any, Dict, Generator, List, Optional, Union, cast
6
+
3
7
  import requests
4
- import json
5
- import re
6
- from typing import List, Dict, Optional, Union, Generator, Any
7
8
 
8
9
  # Import base classes and utility structures
9
- from .base import OpenAICompatibleProvider, BaseChat, BaseCompletions
10
- from .utils import (
11
- ChatCompletionChunk, ChatCompletion, Choice, ChoiceDelta,
12
- ChatCompletionMessage, CompletionUsage
10
+ from webscout.Provider.OPENAI.base import (
11
+ BaseChat,
12
+ BaseCompletions,
13
+ OpenAICompatibleProvider,
14
+ SimpleModelList,
15
+ )
16
+ from webscout.Provider.OPENAI.utils import (
17
+ ChatCompletion,
18
+ ChatCompletionChunk,
19
+ ChatCompletionMessage,
20
+ Choice,
21
+ ChoiceDelta,
22
+ CompletionUsage,
23
+ count_tokens,
13
24
  )
14
25
 
15
26
  # Attempt to import LitAgent, fallback if not available
16
- try:
17
- from webscout.litagent import LitAgent
18
- except ImportError:
19
- pass
27
+ from ...litagent import LitAgent
20
28
 
21
29
  # --- ExaAI Client ---
22
30
 
@@ -25,8 +33,9 @@ BOLD = "\033[1m"
25
33
  RED = "\033[91m"
26
34
  RESET = "\033[0m"
27
35
 
36
+
28
37
  class Completions(BaseCompletions):
29
- def __init__(self, client: 'ExaAI'):
38
+ def __init__(self, client: "ExaAI"):
30
39
  self._client = client
31
40
 
32
41
  def create(
@@ -38,7 +47,9 @@ class Completions(BaseCompletions):
38
47
  stream: bool = False,
39
48
  temperature: Optional[float] = None,
40
49
  top_p: Optional[float] = None,
41
- **kwargs: Any
50
+ timeout: Optional[int] = None,
51
+ proxies: Optional[Dict[str, str]] = None,
52
+ **kwargs: Any,
42
53
  ) -> Union[ChatCompletion, Generator[ChatCompletionChunk, None, None]]:
43
54
  """
44
55
  Creates a model response for the given chat conversation.
@@ -56,7 +67,9 @@ class Completions(BaseCompletions):
56
67
 
57
68
  if has_system_message:
58
69
  # Print warning in bold red
59
- print(f"{BOLD}{RED}Warning: ExaAI does not support system messages, they will be ignored.{RESET}")
70
+ print(
71
+ f"{BOLD}{RED}Warning: ExaAI does not support system messages, they will be ignored.{RESET}"
72
+ )
60
73
 
61
74
  # If no messages left after filtering, raise an error
62
75
  if not filtered_messages:
@@ -66,10 +79,7 @@ class Completions(BaseCompletions):
66
79
  conversation_id = uuid.uuid4().hex[:16]
67
80
 
68
81
  # Prepare the payload for ExaAI API
69
- payload = {
70
- "id": conversation_id,
71
- "messages": filtered_messages
72
- }
82
+ payload = {"id": conversation_id, "messages": filtered_messages}
73
83
 
74
84
  # Add optional parameters if provided
75
85
  if max_tokens is not None and max_tokens > 0:
@@ -90,12 +100,20 @@ class Completions(BaseCompletions):
90
100
  created_time = int(time.time())
91
101
 
92
102
  if stream:
93
- return self._create_stream(request_id, created_time, model, payload)
103
+ return self._create_stream(request_id, created_time, model, payload, timeout, proxies)
94
104
  else:
95
- return self._create_non_stream(request_id, created_time, model, payload)
105
+ return self._create_non_stream(
106
+ request_id, created_time, model, payload, timeout, proxies
107
+ )
96
108
 
97
109
  def _create_stream(
98
- self, request_id: str, created_time: int, model: str, payload: Dict[str, Any]
110
+ self,
111
+ request_id: str,
112
+ created_time: int,
113
+ model: str,
114
+ payload: Dict[str, Any],
115
+ timeout: Optional[int] = None,
116
+ proxies: Optional[Dict[str, str]] = None,
99
117
  ) -> Generator[ChatCompletionChunk, None, None]:
100
118
  try:
101
119
  response = self._client.session.post(
@@ -103,7 +121,8 @@ class Completions(BaseCompletions):
103
121
  headers=self._client.headers,
104
122
  json=payload,
105
123
  stream=True,
106
- timeout=self._client.timeout
124
+ timeout=timeout or self._client.timeout,
125
+ proxies=proxies or getattr(self._client, "proxies", None),
107
126
  )
108
127
 
109
128
  # Handle non-200 responses
@@ -119,73 +138,70 @@ class Completions(BaseCompletions):
119
138
 
120
139
  # Estimate prompt tokens based on message length
121
140
  for msg in payload.get("messages", []):
122
- prompt_tokens += len(msg.get("content", "").split())
141
+ prompt_tokens += count_tokens(msg.get("content", ""))
142
+
143
+ finish_reason = None
144
+ usage = None
123
145
 
124
146
  for line in response.iter_lines(decode_unicode=True):
125
147
  if line:
126
- match = re.search(r'0:"(.*?)"', line)
127
- if match:
128
- content = match.group(1)
129
-
130
- # Format the content (replace escaped newlines)
131
- content = self._client.format_text(content)
132
-
133
- # Update token counts
134
- completion_tokens += 1
135
- total_tokens = prompt_tokens + completion_tokens
136
-
137
- # Create the delta object
138
- delta = ChoiceDelta(
139
- content=content,
140
- role="assistant",
141
- tool_calls=None
142
- )
143
-
144
- # Create the choice object
145
- choice = Choice(
146
- index=0,
147
- delta=delta,
148
- finish_reason=None,
149
- logprobs=None
150
- )
151
-
152
- # Create the chunk object
153
- chunk = ChatCompletionChunk(
154
- id=request_id,
155
- choices=[choice],
156
- created=created_time,
157
- model=model,
158
- system_fingerprint=None
159
- )
160
-
161
- # Convert to dict for proper formatting
162
- chunk_dict = chunk.to_dict()
163
-
164
- # Add usage information to match OpenAI format
165
- usage_dict = {
166
- "prompt_tokens": prompt_tokens,
167
- "completion_tokens": completion_tokens,
168
- "total_tokens": total_tokens,
169
- "estimated_cost": None
170
- }
171
-
172
- chunk_dict["usage"] = usage_dict
173
-
174
- # Return the chunk object for internal processing
175
- yield chunk
148
+ if line.startswith("0:"):
149
+ match = re.search(r'0:"(.*?)"', line)
150
+ if match:
151
+ content = match.group(1)
152
+
153
+ # Format the content (replace escaped newlines)
154
+ content = self._client.format_text(content)
155
+
156
+ # Update token counts
157
+ completion_tokens += count_tokens(content)
158
+ total_tokens = prompt_tokens + completion_tokens
159
+
160
+ # Create the delta object
161
+ delta = ChoiceDelta(content=content, role="assistant", tool_calls=None)
162
+
163
+ # Create the choice object
164
+ choice = Choice(index=0, delta=delta, finish_reason=None, logprobs=None)
165
+
166
+ # Create the chunk object
167
+ chunk = ChatCompletionChunk(
168
+ id=request_id,
169
+ choices=[choice],
170
+ created=created_time,
171
+ model=model,
172
+ system_fingerprint=None,
173
+ )
174
+
175
+ # Convert chunk to dict using Pydantic's API
176
+ if hasattr(chunk, "model_dump"):
177
+ chunk_dict = chunk.model_dump(exclude_none=True)
178
+ else:
179
+ chunk_dict = chunk.dict(exclude_none=True)
180
+
181
+ # Add usage information to match OpenAI format
182
+ usage_dict = {
183
+ "prompt_tokens": prompt_tokens,
184
+ "completion_tokens": completion_tokens,
185
+ "total_tokens": total_tokens,
186
+ "estimated_cost": None,
187
+ }
188
+
189
+ chunk_dict["usage"] = usage_dict
190
+
191
+ # Return the chunk object for internal processing
192
+ yield chunk
193
+ elif line.startswith("e:") or line.startswith("d:"):
194
+ data = json.loads(line[2:])
195
+ if "finishReason" in data:
196
+ finish_reason = data["finishReason"]
197
+ if "usage" in data:
198
+ usage = data["usage"]
176
199
 
177
200
  # Final chunk with finish_reason="stop"
178
- delta = ChoiceDelta(
179
- content=None,
180
- role=None,
181
- tool_calls=None
182
- )
201
+ delta = ChoiceDelta(content=None, role=None, tool_calls=None)
183
202
 
184
203
  choice = Choice(
185
- index=0,
186
- delta=delta,
187
- finish_reason="stop",
188
- logprobs=None
204
+ index=0, delta=delta, finish_reason=finish_reason or "stop", logprobs=None
189
205
  )
190
206
 
191
207
  chunk = ChatCompletionChunk(
@@ -193,16 +209,22 @@ class Completions(BaseCompletions):
193
209
  choices=[choice],
194
210
  created=created_time,
195
211
  model=model,
196
- system_fingerprint=None
212
+ system_fingerprint=None,
197
213
  )
198
214
 
199
- chunk_dict = chunk.to_dict()
200
- chunk_dict["usage"] = {
201
- "prompt_tokens": prompt_tokens,
202
- "completion_tokens": completion_tokens,
203
- "total_tokens": total_tokens,
204
- "estimated_cost": None
205
- }
215
+ if hasattr(chunk, "model_dump"):
216
+ chunk_dict = chunk.model_dump(exclude_none=True)
217
+ else:
218
+ chunk_dict = chunk.dict(exclude_none=True)
219
+ if usage:
220
+ chunk_dict["usage"] = usage
221
+ else:
222
+ chunk_dict["usage"] = {
223
+ "prompt_tokens": prompt_tokens,
224
+ "completion_tokens": completion_tokens,
225
+ "total_tokens": total_tokens,
226
+ "estimated_cost": None,
227
+ }
206
228
 
207
229
  yield chunk
208
230
 
@@ -211,7 +233,13 @@ class Completions(BaseCompletions):
211
233
  raise IOError(f"ExaAI request failed: {e}") from e
212
234
 
213
235
  def _create_non_stream(
214
- self, request_id: str, created_time: int, model: str, payload: Dict[str, Any]
236
+ self,
237
+ request_id: str,
238
+ created_time: int,
239
+ model: str,
240
+ payload: Dict[str, Any],
241
+ timeout: Optional[int] = None,
242
+ proxies: Optional[Dict[str, str]] = None,
215
243
  ) -> ChatCompletion:
216
244
  try:
217
245
  # For non-streaming, we still use streaming internally to collect the full response
@@ -220,7 +248,8 @@ class Completions(BaseCompletions):
220
248
  headers=self._client.headers,
221
249
  json=payload,
222
250
  stream=True,
223
- timeout=self._client.timeout
251
+ timeout=timeout or self._client.timeout,
252
+ proxies=proxies or getattr(self._client, "proxies", None),
224
253
  )
225
254
 
226
255
  # Handle non-200 responses
@@ -231,42 +260,50 @@ class Completions(BaseCompletions):
231
260
 
232
261
  # Collect the full response
233
262
  full_text = ""
263
+ usage = None
264
+ finish_reason = None
234
265
  for line in response.iter_lines(decode_unicode=True):
235
266
  if line:
236
- match = re.search(r'0:"(.*?)"', line)
237
- if match:
238
- content = match.group(1)
239
- full_text += content
267
+ if line.startswith("0:"):
268
+ match = re.search(r'0:"(.*?)"', line)
269
+ if match:
270
+ content = match.group(1)
271
+ full_text += content
272
+ elif line.startswith("e:") or line.startswith("d:"):
273
+ data = json.loads(line[2:])
274
+ if "finishReason" in data:
275
+ finish_reason = data["finishReason"]
276
+ if "usage" in data:
277
+ usage = data["usage"]
240
278
 
241
279
  # Format the text (replace escaped newlines)
242
280
  full_text = self._client.format_text(full_text)
243
281
 
244
- # Estimate token counts
245
- prompt_tokens = 0
246
- for msg in payload.get("messages", []):
247
- prompt_tokens += len(msg.get("content", "").split())
282
+ # Use actual usage if available, else estimate
283
+ if usage:
284
+ prompt_tokens = usage.get("promptTokens", 0)
285
+ completion_tokens = usage.get("completionTokens", 0)
286
+ total_tokens = usage.get("totalTokens", 0)
287
+ else:
288
+ # Estimate token counts
289
+ prompt_tokens = 0
290
+ for msg in payload.get("messages", []):
291
+ prompt_tokens += count_tokens(msg.get("content", ""))
248
292
 
249
- completion_tokens = len(full_text.split())
250
- total_tokens = prompt_tokens + completion_tokens
293
+ completion_tokens = count_tokens(full_text)
294
+ total_tokens = prompt_tokens + completion_tokens
251
295
 
252
296
  # Create the message object
253
- message = ChatCompletionMessage(
254
- role="assistant",
255
- content=full_text
256
- )
297
+ message = ChatCompletionMessage(role="assistant", content=full_text)
257
298
 
258
299
  # Create the choice object
259
- choice = Choice(
260
- index=0,
261
- message=message,
262
- finish_reason="stop"
263
- )
300
+ choice = Choice(index=0, message=message, finish_reason=finish_reason or "stop")
264
301
 
265
302
  # Create the usage object
266
- usage = CompletionUsage(
303
+ usage_obj = CompletionUsage(
267
304
  prompt_tokens=prompt_tokens,
268
305
  completion_tokens=completion_tokens,
269
- total_tokens=total_tokens
306
+ total_tokens=total_tokens,
270
307
  )
271
308
 
272
309
  # Create the completion object
@@ -275,7 +312,7 @@ class Completions(BaseCompletions):
275
312
  choices=[choice],
276
313
  created=created_time,
277
314
  model=model,
278
- usage=usage,
315
+ usage=usage_obj,
279
316
  )
280
317
 
281
318
  return completion
@@ -284,10 +321,12 @@ class Completions(BaseCompletions):
284
321
  print(f"Error during ExaAI non-stream request: {e}")
285
322
  raise IOError(f"ExaAI request failed: {e}") from e
286
323
 
324
+
287
325
  class Chat(BaseChat):
288
- def __init__(self, client: 'ExaAI'):
326
+ def __init__(self, client: "ExaAI"):
289
327
  self.completions = Completions(client)
290
328
 
329
+
291
330
  class ExaAI(OpenAICompatibleProvider):
292
331
  """
293
332
  OpenAI-compatible client for ExaAI API.
@@ -303,47 +342,41 @@ class ExaAI(OpenAICompatibleProvider):
303
342
  ExaAI does not support system messages. Any system messages will be ignored.
304
343
  """
305
344
 
345
+ required_auth = False
306
346
  AVAILABLE_MODELS = ["O3-Mini"]
307
347
 
308
- def __init__(
309
- self,
310
- timeout: Optional[int] = None,
311
- browser: str = "chrome"
312
- ):
348
+ def __init__(self, browser: str = "chrome"):
313
349
  """
314
350
  Initialize the ExaAI client.
315
351
 
316
352
  Args:
317
- timeout: Request timeout in seconds (None for no timeout)
318
- browser: Browser to emulate in user agent
353
+ browser: Browser to emulate in user agent (not used, hardcoded headers)
319
354
  """
320
- self.timeout = timeout
355
+ self.timeout = 60 # Default timeout in seconds
356
+ self.proxies = None # Default proxies
321
357
  self.api_endpoint = "https://o3minichat.exa.ai/api/chat"
322
358
  self.session = requests.Session()
323
359
 
324
- # Initialize LitAgent for user agent generation
325
- agent = LitAgent()
326
- self.fingerprint = agent.generate_fingerprint(browser)
327
-
328
- # Headers for the request
360
+ # Headers based on the curl command
329
361
  self.headers = {
330
362
  "authority": "o3minichat.exa.ai",
331
- "accept": self.fingerprint["accept"],
332
- "accept-encoding": "gzip, deflate, br, zstd",
333
- "accept-language": self.fingerprint["accept_language"],
363
+ "accept": "*/*",
364
+ "accept-language": "en-US,en;q=0.9,en-IN;q=0.8",
334
365
  "content-type": "application/json",
335
366
  "dnt": "1",
336
367
  "origin": "https://o3minichat.exa.ai",
337
368
  "priority": "u=1, i",
338
369
  "referer": "https://o3minichat.exa.ai/",
339
- "sec-ch-ua": self.fingerprint["sec_ch_ua"] or '"Microsoft Edge";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
370
+ "sec-ch-ua": '"Microsoft Edge";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
340
371
  "sec-ch-ua-mobile": "?0",
341
- "sec-ch-ua-platform": f'"{self.fingerprint["platform"]}"',
372
+ "sec-ch-ua-platform": '"Windows"',
342
373
  "sec-fetch-dest": "empty",
343
374
  "sec-fetch-mode": "cors",
344
375
  "sec-fetch-site": "same-origin",
345
376
  "sec-gpc": "1",
346
- "user-agent": self.fingerprint["user_agent"]
377
+ "user-agent": LitAgent().random()
378
+ if LitAgent
379
+ else "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
347
380
  }
348
381
 
349
382
  self.session.headers.update(self.headers)
@@ -364,12 +397,12 @@ class ExaAI(OpenAICompatibleProvider):
364
397
  # Use a more comprehensive approach to handle all escape sequences
365
398
  try:
366
399
  # First handle double backslashes to avoid issues
367
- text = text.replace('\\\\', '\\')
400
+ text = text.replace("\\\\", "\\")
368
401
 
369
402
  # Handle common escape sequences
370
- text = text.replace('\\n', '\n')
371
- text = text.replace('\\r', '\r')
372
- text = text.replace('\\t', '\t')
403
+ text = text.replace("\\n", "\n")
404
+ text = text.replace("\\r", "\r")
405
+ text = text.replace("\\t", "\t")
373
406
  text = text.replace('\\"', '"')
374
407
  text = text.replace("\\'", "'")
375
408
 
@@ -402,3 +435,18 @@ class ExaAI(OpenAICompatibleProvider):
402
435
  # ExaAI only supports O3-Mini, regardless of the input model
403
436
  print(f"Note: ExaAI only supports O3-Mini model. Ignoring provided model '{model}'.")
404
437
  return "O3-Mini"
438
+
439
+ @property
440
+ def models(self) -> SimpleModelList:
441
+ return SimpleModelList(type(self).AVAILABLE_MODELS)
442
+
443
+
444
+ if __name__ == "__main__":
445
+ # Example usage
446
+ client = ExaAI()
447
+ response = client.chat.completions.create(
448
+ model="O3-Mini", messages=[{"role": "user", "content": "Hello, how are you?"}]
449
+ )
450
+ if isinstance(response, ChatCompletion):
451
+ if response.choices[0].message and response.choices[0].message.content:
452
+ print(response.choices[0].message.content)