webscout 8.2.7__py3-none-any.whl → 8.2.9__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 (281) hide show
  1. webscout/AIauto.py +33 -15
  2. webscout/AIbase.py +96 -37
  3. webscout/AIutel.py +703 -250
  4. webscout/Bard.py +441 -323
  5. webscout/Extra/Act.md +309 -0
  6. webscout/Extra/GitToolkit/__init__.py +10 -0
  7. webscout/Extra/GitToolkit/gitapi/README.md +110 -0
  8. webscout/Extra/GitToolkit/gitapi/__init__.py +12 -0
  9. webscout/Extra/GitToolkit/gitapi/repository.py +195 -0
  10. webscout/Extra/GitToolkit/gitapi/user.py +96 -0
  11. webscout/Extra/GitToolkit/gitapi/utils.py +62 -0
  12. webscout/Extra/YTToolkit/README.md +375 -0
  13. webscout/Extra/YTToolkit/YTdownloader.py +957 -0
  14. webscout/Extra/YTToolkit/__init__.py +3 -0
  15. webscout/Extra/YTToolkit/transcriber.py +476 -0
  16. webscout/Extra/YTToolkit/ytapi/README.md +44 -0
  17. webscout/Extra/YTToolkit/ytapi/__init__.py +6 -0
  18. webscout/Extra/YTToolkit/ytapi/channel.py +307 -0
  19. webscout/Extra/YTToolkit/ytapi/errors.py +13 -0
  20. webscout/Extra/YTToolkit/ytapi/extras.py +118 -0
  21. webscout/Extra/YTToolkit/ytapi/https.py +88 -0
  22. webscout/Extra/YTToolkit/ytapi/patterns.py +61 -0
  23. webscout/Extra/YTToolkit/ytapi/playlist.py +59 -0
  24. webscout/Extra/YTToolkit/ytapi/pool.py +8 -0
  25. webscout/Extra/YTToolkit/ytapi/query.py +40 -0
  26. webscout/Extra/YTToolkit/ytapi/stream.py +63 -0
  27. webscout/Extra/YTToolkit/ytapi/utils.py +62 -0
  28. webscout/Extra/YTToolkit/ytapi/video.py +232 -0
  29. webscout/Extra/__init__.py +7 -0
  30. webscout/Extra/autocoder/__init__.py +9 -0
  31. webscout/Extra/autocoder/autocoder.py +1105 -0
  32. webscout/Extra/autocoder/autocoder_utiles.py +332 -0
  33. webscout/Extra/gguf.md +430 -0
  34. webscout/Extra/gguf.py +684 -0
  35. webscout/Extra/tempmail/README.md +488 -0
  36. webscout/Extra/tempmail/__init__.py +28 -0
  37. webscout/Extra/tempmail/async_utils.py +141 -0
  38. webscout/Extra/tempmail/base.py +161 -0
  39. webscout/Extra/tempmail/cli.py +187 -0
  40. webscout/Extra/tempmail/emailnator.py +84 -0
  41. webscout/Extra/tempmail/mail_tm.py +361 -0
  42. webscout/Extra/tempmail/temp_mail_io.py +292 -0
  43. webscout/Extra/weather.md +281 -0
  44. webscout/Extra/weather.py +194 -0
  45. webscout/Extra/weather_ascii.py +76 -0
  46. webscout/Litlogger/README.md +10 -0
  47. webscout/Litlogger/__init__.py +15 -0
  48. webscout/Litlogger/formats.py +4 -0
  49. webscout/Litlogger/handlers.py +103 -0
  50. webscout/Litlogger/levels.py +13 -0
  51. webscout/Litlogger/logger.py +92 -0
  52. webscout/Provider/AI21.py +177 -0
  53. webscout/Provider/AISEARCH/DeepFind.py +254 -0
  54. webscout/Provider/AISEARCH/Perplexity.py +333 -0
  55. webscout/Provider/AISEARCH/README.md +279 -0
  56. webscout/Provider/AISEARCH/__init__.py +9 -0
  57. webscout/Provider/AISEARCH/felo_search.py +202 -0
  58. webscout/Provider/AISEARCH/genspark_search.py +324 -0
  59. webscout/Provider/AISEARCH/hika_search.py +186 -0
  60. webscout/Provider/AISEARCH/iask_search.py +410 -0
  61. webscout/Provider/AISEARCH/monica_search.py +220 -0
  62. webscout/Provider/AISEARCH/scira_search.py +298 -0
  63. webscout/Provider/AISEARCH/webpilotai_search.py +255 -0
  64. webscout/Provider/Aitopia.py +316 -0
  65. webscout/Provider/AllenAI.py +440 -0
  66. webscout/Provider/Andi.py +228 -0
  67. webscout/Provider/Blackboxai.py +791 -0
  68. webscout/Provider/ChatGPTClone.py +237 -0
  69. webscout/Provider/ChatGPTGratis.py +194 -0
  70. webscout/Provider/ChatSandbox.py +342 -0
  71. webscout/Provider/Cloudflare.py +324 -0
  72. webscout/Provider/Cohere.py +208 -0
  73. webscout/Provider/Deepinfra.py +340 -0
  74. webscout/Provider/ExaAI.py +261 -0
  75. webscout/Provider/ExaChat.py +358 -0
  76. webscout/Provider/Flowith.py +217 -0
  77. webscout/Provider/FreeGemini.py +250 -0
  78. webscout/Provider/Gemini.py +169 -0
  79. webscout/Provider/GithubChat.py +369 -0
  80. webscout/Provider/GizAI.py +295 -0
  81. webscout/Provider/Glider.py +225 -0
  82. webscout/Provider/Groq.py +801 -0
  83. webscout/Provider/HF_space/__init__.py +0 -0
  84. webscout/Provider/HF_space/qwen_qwen2.py +206 -0
  85. webscout/Provider/HeckAI.py +375 -0
  86. webscout/Provider/HuggingFaceChat.py +469 -0
  87. webscout/Provider/Hunyuan.py +283 -0
  88. webscout/Provider/Jadve.py +291 -0
  89. webscout/Provider/Koboldai.py +384 -0
  90. webscout/Provider/LambdaChat.py +411 -0
  91. webscout/Provider/Llama3.py +259 -0
  92. webscout/Provider/MCPCore.py +315 -0
  93. webscout/Provider/Marcus.py +198 -0
  94. webscout/Provider/Nemotron.py +218 -0
  95. webscout/Provider/Netwrck.py +270 -0
  96. webscout/Provider/OLLAMA.py +396 -0
  97. webscout/Provider/OPENAI/BLACKBOXAI.py +766 -0
  98. webscout/Provider/OPENAI/Cloudflare.py +378 -0
  99. webscout/Provider/OPENAI/FreeGemini.py +283 -0
  100. webscout/Provider/OPENAI/NEMOTRON.py +232 -0
  101. webscout/Provider/OPENAI/Qwen3.py +283 -0
  102. webscout/Provider/OPENAI/README.md +952 -0
  103. webscout/Provider/OPENAI/TwoAI.py +357 -0
  104. webscout/Provider/OPENAI/__init__.py +40 -0
  105. webscout/Provider/OPENAI/ai4chat.py +293 -0
  106. webscout/Provider/OPENAI/api.py +969 -0
  107. webscout/Provider/OPENAI/base.py +249 -0
  108. webscout/Provider/OPENAI/c4ai.py +373 -0
  109. webscout/Provider/OPENAI/chatgpt.py +556 -0
  110. webscout/Provider/OPENAI/chatgptclone.py +494 -0
  111. webscout/Provider/OPENAI/chatsandbox.py +173 -0
  112. webscout/Provider/OPENAI/copilot.py +242 -0
  113. webscout/Provider/OPENAI/deepinfra.py +322 -0
  114. webscout/Provider/OPENAI/e2b.py +1414 -0
  115. webscout/Provider/OPENAI/exaai.py +417 -0
  116. webscout/Provider/OPENAI/exachat.py +444 -0
  117. webscout/Provider/OPENAI/flowith.py +162 -0
  118. webscout/Provider/OPENAI/freeaichat.py +359 -0
  119. webscout/Provider/OPENAI/glider.py +326 -0
  120. webscout/Provider/OPENAI/groq.py +364 -0
  121. webscout/Provider/OPENAI/heckai.py +308 -0
  122. webscout/Provider/OPENAI/llmchatco.py +335 -0
  123. webscout/Provider/OPENAI/mcpcore.py +389 -0
  124. webscout/Provider/OPENAI/multichat.py +376 -0
  125. webscout/Provider/OPENAI/netwrck.py +357 -0
  126. webscout/Provider/OPENAI/oivscode.py +287 -0
  127. webscout/Provider/OPENAI/opkfc.py +496 -0
  128. webscout/Provider/OPENAI/pydantic_imports.py +172 -0
  129. webscout/Provider/OPENAI/scirachat.py +477 -0
  130. webscout/Provider/OPENAI/sonus.py +304 -0
  131. webscout/Provider/OPENAI/standardinput.py +433 -0
  132. webscout/Provider/OPENAI/textpollinations.py +339 -0
  133. webscout/Provider/OPENAI/toolbaz.py +413 -0
  134. webscout/Provider/OPENAI/typefully.py +355 -0
  135. webscout/Provider/OPENAI/typegpt.py +364 -0
  136. webscout/Provider/OPENAI/uncovrAI.py +463 -0
  137. webscout/Provider/OPENAI/utils.py +318 -0
  138. webscout/Provider/OPENAI/venice.py +431 -0
  139. webscout/Provider/OPENAI/wisecat.py +387 -0
  140. webscout/Provider/OPENAI/writecream.py +163 -0
  141. webscout/Provider/OPENAI/x0gpt.py +365 -0
  142. webscout/Provider/OPENAI/yep.py +382 -0
  143. webscout/Provider/OpenGPT.py +209 -0
  144. webscout/Provider/Openai.py +496 -0
  145. webscout/Provider/PI.py +429 -0
  146. webscout/Provider/Perplexitylabs.py +415 -0
  147. webscout/Provider/QwenLM.py +254 -0
  148. webscout/Provider/Reka.py +214 -0
  149. webscout/Provider/StandardInput.py +290 -0
  150. webscout/Provider/TTI/README.md +82 -0
  151. webscout/Provider/TTI/__init__.py +7 -0
  152. webscout/Provider/TTI/aiarta.py +365 -0
  153. webscout/Provider/TTI/artbit.py +0 -0
  154. webscout/Provider/TTI/base.py +64 -0
  155. webscout/Provider/TTI/fastflux.py +200 -0
  156. webscout/Provider/TTI/magicstudio.py +201 -0
  157. webscout/Provider/TTI/piclumen.py +203 -0
  158. webscout/Provider/TTI/pixelmuse.py +225 -0
  159. webscout/Provider/TTI/pollinations.py +221 -0
  160. webscout/Provider/TTI/utils.py +11 -0
  161. webscout/Provider/TTS/README.md +192 -0
  162. webscout/Provider/TTS/__init__.py +10 -0
  163. webscout/Provider/TTS/base.py +159 -0
  164. webscout/Provider/TTS/deepgram.py +156 -0
  165. webscout/Provider/TTS/elevenlabs.py +111 -0
  166. webscout/Provider/TTS/gesserit.py +128 -0
  167. webscout/Provider/TTS/murfai.py +113 -0
  168. webscout/Provider/TTS/openai_fm.py +129 -0
  169. webscout/Provider/TTS/parler.py +111 -0
  170. webscout/Provider/TTS/speechma.py +580 -0
  171. webscout/Provider/TTS/sthir.py +94 -0
  172. webscout/Provider/TTS/streamElements.py +333 -0
  173. webscout/Provider/TTS/utils.py +280 -0
  174. webscout/Provider/TeachAnything.py +229 -0
  175. webscout/Provider/TextPollinationsAI.py +308 -0
  176. webscout/Provider/TwoAI.py +475 -0
  177. webscout/Provider/TypliAI.py +305 -0
  178. webscout/Provider/UNFINISHED/ChatHub.py +209 -0
  179. webscout/Provider/UNFINISHED/Youchat.py +330 -0
  180. webscout/Provider/UNFINISHED/liner_api_request.py +263 -0
  181. webscout/Provider/UNFINISHED/puterjs.py +635 -0
  182. webscout/Provider/UNFINISHED/test_lmarena.py +119 -0
  183. webscout/Provider/Venice.py +258 -0
  184. webscout/Provider/VercelAI.py +253 -0
  185. webscout/Provider/WiseCat.py +233 -0
  186. webscout/Provider/WrDoChat.py +370 -0
  187. webscout/Provider/Writecream.py +246 -0
  188. webscout/Provider/WritingMate.py +269 -0
  189. webscout/Provider/__init__.py +174 -0
  190. webscout/Provider/ai4chat.py +174 -0
  191. webscout/Provider/akashgpt.py +335 -0
  192. webscout/Provider/asksteve.py +220 -0
  193. webscout/Provider/cerebras.py +290 -0
  194. webscout/Provider/chatglm.py +215 -0
  195. webscout/Provider/cleeai.py +213 -0
  196. webscout/Provider/copilot.py +425 -0
  197. webscout/Provider/elmo.py +283 -0
  198. webscout/Provider/freeaichat.py +285 -0
  199. webscout/Provider/geminiapi.py +208 -0
  200. webscout/Provider/granite.py +235 -0
  201. webscout/Provider/hermes.py +266 -0
  202. webscout/Provider/julius.py +223 -0
  203. webscout/Provider/koala.py +170 -0
  204. webscout/Provider/learnfastai.py +325 -0
  205. webscout/Provider/llama3mitril.py +215 -0
  206. webscout/Provider/llmchat.py +258 -0
  207. webscout/Provider/llmchatco.py +306 -0
  208. webscout/Provider/lmarena.py +198 -0
  209. webscout/Provider/meta.py +801 -0
  210. webscout/Provider/multichat.py +364 -0
  211. webscout/Provider/oivscode.py +309 -0
  212. webscout/Provider/samurai.py +224 -0
  213. webscout/Provider/scira_chat.py +299 -0
  214. webscout/Provider/scnet.py +243 -0
  215. webscout/Provider/searchchat.py +292 -0
  216. webscout/Provider/sonus.py +258 -0
  217. webscout/Provider/talkai.py +194 -0
  218. webscout/Provider/toolbaz.py +353 -0
  219. webscout/Provider/turboseek.py +266 -0
  220. webscout/Provider/typefully.py +202 -0
  221. webscout/Provider/typegpt.py +289 -0
  222. webscout/Provider/uncovr.py +368 -0
  223. webscout/Provider/x0gpt.py +299 -0
  224. webscout/Provider/yep.py +389 -0
  225. webscout/__init__.py +4 -2
  226. webscout/cli.py +3 -28
  227. webscout/client.py +70 -0
  228. webscout/conversation.py +35 -35
  229. webscout/litagent/Readme.md +276 -0
  230. webscout/litagent/__init__.py +29 -0
  231. webscout/litagent/agent.py +455 -0
  232. webscout/litagent/constants.py +60 -0
  233. webscout/litprinter/__init__.py +59 -0
  234. webscout/optimizers.py +419 -419
  235. webscout/scout/README.md +404 -0
  236. webscout/scout/__init__.py +8 -0
  237. webscout/scout/core/__init__.py +7 -0
  238. webscout/scout/core/crawler.py +210 -0
  239. webscout/scout/core/scout.py +607 -0
  240. webscout/scout/core/search_result.py +96 -0
  241. webscout/scout/core/text_analyzer.py +63 -0
  242. webscout/scout/core/text_utils.py +277 -0
  243. webscout/scout/core/web_analyzer.py +52 -0
  244. webscout/scout/element.py +478 -0
  245. webscout/scout/parsers/__init__.py +69 -0
  246. webscout/scout/parsers/html5lib_parser.py +172 -0
  247. webscout/scout/parsers/html_parser.py +236 -0
  248. webscout/scout/parsers/lxml_parser.py +178 -0
  249. webscout/scout/utils.py +37 -0
  250. webscout/swiftcli/Readme.md +323 -0
  251. webscout/swiftcli/__init__.py +95 -0
  252. webscout/swiftcli/core/__init__.py +7 -0
  253. webscout/swiftcli/core/cli.py +297 -0
  254. webscout/swiftcli/core/context.py +104 -0
  255. webscout/swiftcli/core/group.py +241 -0
  256. webscout/swiftcli/decorators/__init__.py +28 -0
  257. webscout/swiftcli/decorators/command.py +221 -0
  258. webscout/swiftcli/decorators/options.py +220 -0
  259. webscout/swiftcli/decorators/output.py +252 -0
  260. webscout/swiftcli/exceptions.py +21 -0
  261. webscout/swiftcli/plugins/__init__.py +9 -0
  262. webscout/swiftcli/plugins/base.py +135 -0
  263. webscout/swiftcli/plugins/manager.py +269 -0
  264. webscout/swiftcli/utils/__init__.py +59 -0
  265. webscout/swiftcli/utils/formatting.py +252 -0
  266. webscout/swiftcli/utils/parsing.py +267 -0
  267. webscout/version.py +1 -1
  268. webscout/webscout_search.py +2 -182
  269. webscout/webscout_search_async.py +1 -179
  270. webscout/zeroart/README.md +89 -0
  271. webscout/zeroart/__init__.py +135 -0
  272. webscout/zeroart/base.py +66 -0
  273. webscout/zeroart/effects.py +101 -0
  274. webscout/zeroart/fonts.py +1239 -0
  275. {webscout-8.2.7.dist-info → webscout-8.2.9.dist-info}/METADATA +262 -83
  276. webscout-8.2.9.dist-info/RECORD +289 -0
  277. {webscout-8.2.7.dist-info → webscout-8.2.9.dist-info}/WHEEL +1 -1
  278. {webscout-8.2.7.dist-info → webscout-8.2.9.dist-info}/entry_points.txt +1 -0
  279. webscout-8.2.7.dist-info/RECORD +0 -26
  280. {webscout-8.2.7.dist-info → webscout-8.2.9.dist-info}/licenses/LICENSE.md +0 -0
  281. {webscout-8.2.7.dist-info → webscout-8.2.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,357 @@
1
+ import time
2
+ import uuid
3
+ import requests
4
+ import json
5
+ from typing import List, Dict, Optional, Union, Generator, Any
6
+
7
+ from webscout.Provider.yep import T
8
+ from webscout.litagent import LitAgent
9
+ from .base import BaseChat, BaseCompletions, OpenAICompatibleProvider
10
+ from .utils import (
11
+ ChatCompletion,
12
+ ChatCompletionChunk,
13
+ Choice,
14
+ ChatCompletionMessage,
15
+ ChoiceDelta,
16
+ CompletionUsage,
17
+ format_prompt,
18
+ get_system_prompt,
19
+ count_tokens
20
+ )
21
+
22
+ # ANSI escape codes for formatting
23
+ BOLD = "\033[1m"
24
+ RED = "\033[91m"
25
+ RESET = "\033[0m"
26
+
27
+ class Completions(BaseCompletions):
28
+ def __init__(self, client: 'Netwrck'):
29
+ self._client = client
30
+
31
+ def create(
32
+ self,
33
+ *,
34
+ model: str,
35
+ messages: List[Dict[str, str]],
36
+ max_tokens: Optional[int] = None, # Not used directly but kept for compatibility
37
+ stream: bool = False,
38
+ temperature: Optional[float] = None,
39
+ top_p: Optional[float] = None,
40
+ **kwargs: Any
41
+ ) -> Union[ChatCompletion, Generator[ChatCompletionChunk, None, None]]:
42
+ """
43
+ Creates a model response for the given chat conversation.
44
+ Mimics openai.chat.completions.create
45
+ """
46
+ # Format the messages using the format_prompt utility
47
+ # This creates a conversation in the format: "User: message\nAssistant: response\nUser: message\nAssistant:"
48
+ formatted_prompt = format_prompt(messages, add_special_tokens=True, do_continue=True)
49
+
50
+
51
+ # Prepare the payload for Netwrck API
52
+ payload = {
53
+ "query": formatted_prompt,
54
+ "context": get_system_prompt(messages),
55
+ "examples": [],
56
+ "model_name": self._client.convert_model_name(model),
57
+ "greeting": self._client.greeting
58
+ }
59
+
60
+ request_id = f"chatcmpl-{uuid.uuid4()}"
61
+ created_time = int(time.time())
62
+
63
+ if stream:
64
+ return self._create_stream(request_id, created_time, model, payload)
65
+ else:
66
+ return self._create_non_stream(request_id, created_time, model, payload)
67
+
68
+ def _create_stream(
69
+ self, request_id: str, created_time: int, model: str, payload: Dict[str, Any]
70
+ ) -> Generator[ChatCompletionChunk, None, None]:
71
+ try:
72
+ response = self._client.session.post(
73
+ "https://netwrck.com/api/chatpred_or",
74
+ json=payload,
75
+ headers=self._client.headers,
76
+ timeout=self._client.timeout,
77
+ stream=True
78
+ )
79
+ response.raise_for_status()
80
+
81
+ # Track token usage across chunks
82
+ completion_tokens = 0
83
+ streaming_text = ""
84
+
85
+ for line in response.iter_lines():
86
+ if not line:
87
+ continue
88
+
89
+ try:
90
+ decoded_line = line.decode('utf-8').strip('"')
91
+ if decoded_line:
92
+ # Format the decoded line using the client's formatter
93
+ formatted_content = self._client.format_text(decoded_line)
94
+ streaming_text += formatted_content
95
+ completion_tokens += count_tokens(formatted_content)
96
+
97
+ # Create a delta object for this chunk
98
+ delta = ChoiceDelta(content=formatted_content)
99
+ choice = Choice(index=0, delta=delta, finish_reason=None)
100
+
101
+ chunk = ChatCompletionChunk(
102
+ id=request_id,
103
+ choices=[choice],
104
+ created=created_time,
105
+ model=model,
106
+ )
107
+
108
+ yield chunk
109
+ except Exception:
110
+ continue
111
+
112
+ # Final chunk with finish_reason
113
+ delta = ChoiceDelta(content=None)
114
+ choice = Choice(index=0, delta=delta, finish_reason="stop")
115
+
116
+ chunk = ChatCompletionChunk(
117
+ id=request_id,
118
+ choices=[choice],
119
+ created=created_time,
120
+ model=model,
121
+ )
122
+
123
+ yield chunk
124
+
125
+ except requests.exceptions.RequestException as e:
126
+ print(f"{RED}Error during Netwrck stream request: {e}{RESET}")
127
+ raise IOError(f"Netwrck request failed: {e}") from e
128
+
129
+ def _create_non_stream(
130
+ self, request_id: str, created_time: int, model: str, payload: Dict[str, Any]
131
+ ) -> ChatCompletion:
132
+ try:
133
+ response = self._client.session.post(
134
+ "https://netwrck.com/api/chatpred_or",
135
+ json=payload,
136
+ headers=self._client.headers,
137
+ timeout=self._client.timeout
138
+ )
139
+ response.raise_for_status()
140
+
141
+ # Process the response
142
+ raw_response = response.text.strip('"')
143
+ # Format the full response using the client's formatter
144
+ full_response = self._client.format_text(raw_response)
145
+
146
+ # Create usage statistics using count_tokens
147
+ prompt_tokens = count_tokens(payload.get("query", ""))
148
+ completion_tokens = count_tokens(full_response)
149
+ total_tokens = prompt_tokens + completion_tokens
150
+
151
+ usage = CompletionUsage(
152
+ prompt_tokens=prompt_tokens,
153
+ completion_tokens=completion_tokens,
154
+ total_tokens=total_tokens
155
+ )
156
+
157
+ # Create the message object
158
+ message = ChatCompletionMessage(
159
+ role="assistant",
160
+ content=full_response
161
+ )
162
+
163
+ # Create the choice object
164
+ choice = Choice(
165
+ index=0,
166
+ message=message,
167
+ finish_reason="stop"
168
+ )
169
+
170
+ # Create the completion object
171
+ completion = ChatCompletion(
172
+ id=request_id,
173
+ choices=[choice],
174
+ created=created_time,
175
+ model=model,
176
+ usage=usage,
177
+ )
178
+
179
+ return completion
180
+
181
+ except Exception as e:
182
+ print(f"{RED}Error during Netwrck non-stream request: {e}{RESET}")
183
+ raise IOError(f"Netwrck request failed: {e}") from e
184
+
185
+ class Chat(BaseChat):
186
+ def __init__(self, client: 'Netwrck'):
187
+ self.completions = Completions(client)
188
+
189
+ class Netwrck(OpenAICompatibleProvider):
190
+ """
191
+ OpenAI-compatible client for Netwrck API.
192
+
193
+ Usage:
194
+ client = Netwrck()
195
+ response = client.chat.completions.create(
196
+ model="anthropic/claude-3-7-sonnet-20250219",
197
+ messages=[{"role": "user", "content": "Hello!"}]
198
+ )
199
+ print(response.choices[0].message.content)
200
+ """
201
+
202
+ AVAILABLE_MODELS = [
203
+ "neversleep/llama-3-lumimaid-8b:extended",
204
+ "x-ai/grok-2",
205
+ "anthropic/claude-3-7-sonnet-20250219",
206
+ "sao10k/l3-euryale-70b",
207
+ "openai/gpt-4.1-mini",
208
+ "gryphe/mythomax-l2-13b",
209
+ "google/gemini-pro-1.5",
210
+ "google/gemini-2.5-flash-preview-04-17",
211
+ "nvidia/llama-3.1-nemotron-70b-instruct",
212
+ "deepseek/deepseek-r1",
213
+ "deepseek/deepseek-chat"
214
+
215
+ ]
216
+
217
+ # Default greeting used by Netwrck
218
+ greeting = """Hello! I'm a helpful assistant. How can I help you today?"""
219
+
220
+ def __init__(
221
+ self,
222
+ timeout: int = 30,
223
+ temperature: float = 0.7,
224
+ top_p: float = 0.8,
225
+ system_prompt: str = "You are a helpful assistant."
226
+ ):
227
+ """
228
+ Initialize the Netwrck client.
229
+
230
+ Args:
231
+ timeout: Request timeout in seconds.
232
+ temperature: Temperature for response generation.
233
+ top_p: Top-p sampling parameter.
234
+ system_prompt: System prompt to use for the conversation.
235
+ """
236
+ self.timeout = timeout
237
+ self.temperature = temperature
238
+ self.top_p = top_p
239
+ self.system_prompt = system_prompt
240
+
241
+ # Initialize LitAgent for user agent generation
242
+ agent = LitAgent()
243
+
244
+ self.headers = {
245
+ 'authority': 'netwrck.com',
246
+ 'accept': '*/*',
247
+ 'accept-language': 'en-US,en;q=0.9',
248
+ 'content-type': 'application/json',
249
+ 'origin': 'https://netwrck.com',
250
+ 'referer': 'https://netwrck.com/',
251
+ 'user-agent': agent.random()
252
+ }
253
+
254
+ self.session = requests.Session()
255
+ self.session.headers.update(self.headers)
256
+
257
+ # Initialize the chat interface
258
+ self.chat = Chat(self)
259
+
260
+ def format_text(self, text: str) -> str:
261
+ """
262
+ Format text by replacing escaped newlines with actual newlines.
263
+
264
+ Args:
265
+ text: Text to format
266
+
267
+ Returns:
268
+ Formatted text
269
+ """
270
+ # Use a more comprehensive approach to handle all escape sequences
271
+ try:
272
+ # First handle double backslashes to avoid issues
273
+ text = text.replace('\\\\', '\\')
274
+
275
+ # Handle common escape sequences
276
+ text = text.replace('\\n', '\n')
277
+ text = text.replace('\\r', '\r')
278
+ text = text.replace('\\t', '\t')
279
+ text = text.replace('\\"', '"')
280
+ text = text.replace("\\'", "'")
281
+
282
+ # Handle any remaining escape sequences using JSON decoding
283
+ # This is a fallback in case there are other escape sequences
284
+ try:
285
+ # Add quotes to make it a valid JSON string
286
+ json_str = f'"{text}"'
287
+ # Use json module to decode all escape sequences
288
+ decoded = json.loads(json_str)
289
+ return decoded
290
+ except json.JSONDecodeError:
291
+ # If JSON decoding fails, return the text with the replacements we've already done
292
+ return text
293
+ except Exception as e:
294
+ # If any error occurs, return the original text
295
+ print(f"Warning: Error formatting text: {e}")
296
+ return text
297
+
298
+ def convert_model_name(self, model: str) -> str:
299
+ """
300
+ Ensure the model name is in the correct format.
301
+ """
302
+ if model in self.AVAILABLE_MODELS:
303
+ return model
304
+
305
+ # Try to find a matching model
306
+ for available_model in self.AVAILABLE_MODELS:
307
+ if model.lower() in available_model.lower():
308
+ return available_model
309
+
310
+ # Default to Claude if no match
311
+ print(f"{BOLD}Warning: Model '{model}' not found, using default model 'anthropic/claude-3-7-sonnet-20250219'{RESET}")
312
+ return "anthropic/claude-3-7-sonnet-20250219"
313
+
314
+ @property
315
+ def models(self):
316
+ class _ModelList:
317
+ def list(inner_self):
318
+ return type(self).AVAILABLE_MODELS
319
+ return _ModelList()
320
+
321
+ # Simple test if run directly
322
+ if __name__ == "__main__":
323
+ print("-" * 80)
324
+ print(f"{'Model':<50} {'Status':<10} {'Response'}")
325
+ print("-" * 80)
326
+
327
+ # Test a subset of models to avoid excessive API calls
328
+ test_models = [
329
+ "anthropic/claude-3-7-sonnet-20250219",
330
+ "openai/gpt-4o-mini",
331
+ "deepseek/deepseek-chat"
332
+ ]
333
+
334
+ for model in test_models:
335
+ try:
336
+ client = Netwrck(timeout=60)
337
+ # Test with a simple conversation to demonstrate format_prompt usage
338
+ response = client.chat.completions.create(
339
+ model=model,
340
+ messages=[
341
+ {"role": "system", "content": "You are a helpful assistant."},
342
+ {"role": "user", "content": "Say 'Hello' in one word"},
343
+ ],
344
+ stream=False
345
+ )
346
+
347
+ if response and response.choices and response.choices[0].message.content:
348
+ status = "✓"
349
+ # Truncate response if too long
350
+ display_text = response.choices[0].message.content.strip()
351
+ display_text = display_text[:50] + "..." if len(display_text) > 50 else display_text
352
+ else:
353
+ status = "✗"
354
+ display_text = "Empty or invalid response"
355
+ print(f"{model:<50} {status:<10} {display_text}")
356
+ except Exception as e:
357
+ print(f"{model:<50} {'✗':<10} {str(e)}")
@@ -0,0 +1,287 @@
1
+ import random
2
+ import secrets
3
+ import requests
4
+ import json
5
+ import time
6
+ import uuid
7
+ import string
8
+ from typing import List, Dict, Optional, Union, Generator, Any
9
+
10
+ # Import base classes and utility structures
11
+ from webscout.Provider.OPENAI.base import OpenAICompatibleProvider, BaseChat, BaseCompletions
12
+ from webscout.Provider.OPENAI.utils import (
13
+ ChatCompletionChunk, ChatCompletion, Choice, ChoiceDelta,
14
+ ChatCompletionMessage, CompletionUsage
15
+ )
16
+
17
+ # --- oivscode Client ---
18
+
19
+ class Completions(BaseCompletions):
20
+ def __init__(self, client: 'oivscode'):
21
+ self._client = client
22
+
23
+ def create(
24
+ self,
25
+ *,
26
+ model: str,
27
+ messages: List[Dict[str, str]],
28
+ max_tokens: Optional[int] = 2049,
29
+ stream: bool = False,
30
+ temperature: Optional[float] = None,
31
+ top_p: Optional[float] = None,
32
+ **kwargs: Any
33
+ ) -> Union[ChatCompletion, Generator[ChatCompletionChunk, None, None]]:
34
+ """
35
+ Creates a model response for the given chat conversation.
36
+ Mimics openai.chat.completions.create
37
+ """
38
+ payload = {
39
+ "model": model,
40
+ "messages": messages,
41
+ "max_tokens": max_tokens,
42
+ "stream": stream,
43
+ }
44
+ if temperature is not None:
45
+ payload["temperature"] = temperature
46
+ if top_p is not None:
47
+ payload["top_p"] = top_p
48
+
49
+ payload.update(kwargs)
50
+
51
+ request_id = f"chatcmpl-{uuid.uuid4()}"
52
+ created_time = int(time.time())
53
+
54
+ if stream:
55
+ return self._create_stream(request_id, created_time, model, payload)
56
+ else:
57
+ return self._create_non_stream(request_id, created_time, model, payload)
58
+
59
+ def _post_with_retry(self, payload, stream=False):
60
+ """
61
+ Try all endpoints until one succeeds or all fail.
62
+ """
63
+ last_exception = None
64
+ for endpoint in self._client.api_endpoints:
65
+ try:
66
+ response = self._client.session.post(
67
+ endpoint,
68
+ headers=self._client.headers,
69
+ json=payload,
70
+ stream=stream,
71
+ timeout=self._client.timeout
72
+ )
73
+ response.raise_for_status()
74
+ self._client.base_url = endpoint # Update to working endpoint
75
+ return response
76
+ except requests.exceptions.RequestException as e:
77
+ last_exception = e
78
+ continue
79
+ raise IOError(f"All oivscode endpoints failed: {last_exception}") from last_exception
80
+
81
+ def _create_stream(
82
+ self, request_id: str, created_time: int, model: str, payload: Dict[str, Any]
83
+ ) -> Generator[ChatCompletionChunk, None, None]:
84
+ try:
85
+ response = self._post_with_retry(payload, stream=True)
86
+ prompt_tokens = 0
87
+ completion_tokens = 0
88
+ total_tokens = 0
89
+
90
+ for line in response.iter_lines():
91
+ if line:
92
+ decoded_line = line.decode('utf-8').strip()
93
+
94
+ if decoded_line.startswith("data: "):
95
+ json_str = decoded_line[6:]
96
+ if json_str == "[DONE]":
97
+ break
98
+ try:
99
+ data = json.loads(json_str)
100
+ choice_data = data.get('choices', [{}])[0]
101
+ delta_data = choice_data.get('delta', {})
102
+ finish_reason = choice_data.get('finish_reason')
103
+
104
+ usage_data = data.get('usage', {})
105
+ if usage_data:
106
+ prompt_tokens = usage_data.get('prompt_tokens', prompt_tokens)
107
+ completion_tokens = usage_data.get('completion_tokens', completion_tokens)
108
+ total_tokens = usage_data.get('total_tokens', total_tokens)
109
+
110
+ delta = ChoiceDelta(
111
+ content=delta_data.get('content'),
112
+ role=delta_data.get('role'),
113
+ tool_calls=delta_data.get('tool_calls')
114
+ )
115
+
116
+ choice = Choice(
117
+ index=choice_data.get('index', 0),
118
+ delta=delta,
119
+ finish_reason=finish_reason,
120
+ logprobs=choice_data.get('logprobs')
121
+ )
122
+
123
+ chunk = ChatCompletionChunk(
124
+ id=request_id,
125
+ choices=[choice],
126
+ created=created_time,
127
+ model=model,
128
+ system_fingerprint=data.get('system_fingerprint')
129
+ )
130
+
131
+ if hasattr(chunk, "model_dump"):
132
+ chunk_dict = chunk.model_dump(exclude_none=True)
133
+ else:
134
+ chunk_dict = chunk.dict(exclude_none=True)
135
+
136
+ usage_dict = {
137
+ "prompt_tokens": prompt_tokens or 10,
138
+ "completion_tokens": completion_tokens or (len(delta_data.get('content', '')) if delta_data.get('content') else 0),
139
+ "total_tokens": total_tokens or (10 + (len(delta_data.get('content', '')) if delta_data.get('content') else 0)),
140
+ "estimated_cost": None
141
+ }
142
+
143
+ if delta_data.get('content'):
144
+ completion_tokens += 1
145
+ total_tokens = prompt_tokens + completion_tokens
146
+ usage_dict["completion_tokens"] = completion_tokens
147
+ usage_dict["total_tokens"] = total_tokens
148
+
149
+ chunk_dict["usage"] = usage_dict
150
+
151
+ yield chunk
152
+ except json.JSONDecodeError:
153
+ print(f"Warning: Could not decode JSON line: {json_str}")
154
+ continue
155
+ except requests.exceptions.RequestException as e:
156
+ print(f"Error during oivscode stream request: {e}")
157
+ raise IOError(f"oivscode request failed: {e}") from e
158
+ except Exception as e:
159
+ print(f"Error processing oivscode stream: {e}")
160
+ raise
161
+
162
+ def _create_non_stream(
163
+ self, request_id: str, created_time: int, model: str, payload: Dict[str, Any]
164
+ ) -> ChatCompletion:
165
+ try:
166
+ response = self._post_with_retry(payload, stream=False)
167
+ data = response.json()
168
+
169
+ choices_data = data.get('choices', [])
170
+ usage_data = data.get('usage', {})
171
+
172
+ choices = []
173
+ for choice_d in choices_data:
174
+ message_d = choice_d.get('message', {})
175
+ message = ChatCompletionMessage(
176
+ role=message_d.get('role', 'assistant'),
177
+ content=message_d.get('content', '')
178
+ )
179
+ choice = Choice(
180
+ index=choice_d.get('index', 0),
181
+ message=message,
182
+ finish_reason=choice_d.get('finish_reason', 'stop')
183
+ )
184
+ choices.append(choice)
185
+
186
+ usage = CompletionUsage(
187
+ prompt_tokens=usage_data.get('prompt_tokens', 0),
188
+ completion_tokens=usage_data.get('completion_tokens', 0),
189
+ total_tokens=usage_data.get('total_tokens', 0)
190
+ )
191
+
192
+ completion = ChatCompletion(
193
+ id=request_id,
194
+ choices=choices,
195
+ created=created_time,
196
+ model=data.get('model', model),
197
+ usage=usage,
198
+ )
199
+ return completion
200
+
201
+ except requests.exceptions.RequestException as e:
202
+ print(f"Error during oivscode non-stream request: {e}")
203
+ raise IOError(f"oivscode request failed: {e}") from e
204
+ except Exception as e:
205
+ print(f"Error processing oivscode response: {e}")
206
+ raise
207
+
208
+ class Chat(BaseChat):
209
+ def __init__(self, client: 'oivscode'):
210
+ self.completions = Completions(client)
211
+
212
+ class oivscode(OpenAICompatibleProvider):
213
+
214
+ AVAILABLE_MODELS = [
215
+ "*",
216
+ "Qwen/Qwen2.5-72B-Instruct-Turbo",
217
+ "Qwen/Qwen2.5-Coder-32B-Instruct",
218
+ "claude-3-5-sonnet-20240620",
219
+ "claude-3-5-sonnet-20241022",
220
+ "claude-3-7-sonnet-20250219",
221
+ "custom/blackbox-base",
222
+ "custom/blackbox-pro",
223
+ "custom/blackbox-pro-designer",
224
+ "custom/blackbox-pro-plus",
225
+ "deepseek-r1",
226
+ "deepseek-v3",
227
+ "deepseek/deepseek-chat",
228
+ "gemini-2.5-pro-preview-03-25",
229
+ "gpt-4o-mini",
230
+ "grok-3-beta",
231
+ "image-gen",
232
+ "llama-4-maverick-17b-128e-instruct-fp8",
233
+ "o1",
234
+ "o3-mini",
235
+ "o4-mini",
236
+ "transcribe",
237
+ "anthropic/claude-sonnet-4"
238
+ ]
239
+
240
+ def __init__(self, timeout: Optional[int] = None):
241
+ self.timeout = timeout
242
+ self.api_endpoints = [
243
+ "https://oi-vscode-server.onrender.com/v1/chat/completions",
244
+ "https://oi-vscode-server-2.onrender.com/v1/chat/completions",
245
+ "https://oi-vscode-server-5.onrender.com/v1/chat/completions",
246
+ "https://oi-vscode-server-0501.onrender.com/v1/chat/completions"
247
+ ]
248
+ self.api_endpoint = random.choice(self.api_endpoints)
249
+ self.base_url = self.api_endpoint
250
+ self.session = requests.Session()
251
+ self.headers = {
252
+ "accept": "*/*",
253
+ "accept-language": "en-US,en;q=0.9,en-GB;q=0.8,en-IN;q=0.7",
254
+ "cache-control": "no-cache",
255
+ "content-type": "application/json",
256
+ "pragma": "no-cache",
257
+ "priority": "u=1, i",
258
+ "sec-ch-ua": '"Not A(Brand";v="8", "Chromium";v="132", "Microsoft Edge";v="132"',
259
+ "sec-ch-ua-mobile": "?0",
260
+ "sec-ch-ua-platform": '"Windows"',
261
+ "sec-fetch-dest": "empty",
262
+ "sec-fetch-mode": "cors",
263
+ "sec-fetch-site": "same-site",
264
+ }
265
+ self.userid = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(21))
266
+ self.headers["userid"] = self.userid
267
+ self.session.headers.update(self.headers)
268
+ self.chat = Chat(self)
269
+
270
+ @property
271
+ def models(self):
272
+ class _ModelList:
273
+ def list(inner_self):
274
+ return type(self).AVAILABLE_MODELS
275
+ return _ModelList()
276
+
277
+ if __name__ == "__main__":
278
+ # Example usage
279
+ client = oivscode()
280
+ chat = client.chat
281
+ response = chat.completions.create(
282
+ model="Qwen/Qwen2.5-72B-Instruct-Turbo",
283
+ messages=[{"role": "user", "content": "Hello, how are you?"}],
284
+ max_tokens=50,
285
+ stream=False
286
+ )
287
+ print(response)