webscout 8.3__py3-none-any.whl → 8.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webscout might be problematic. Click here for more details.

Files changed (120) hide show
  1. webscout/AIauto.py +4 -4
  2. webscout/AIbase.py +61 -1
  3. webscout/AIutel.py +46 -53
  4. webscout/Bing_search.py +418 -0
  5. webscout/Extra/YTToolkit/ytapi/patterns.py +45 -45
  6. webscout/Extra/YTToolkit/ytapi/stream.py +1 -1
  7. webscout/Extra/YTToolkit/ytapi/video.py +10 -10
  8. webscout/Extra/autocoder/autocoder_utiles.py +1 -1
  9. webscout/Extra/gguf.py +706 -177
  10. webscout/Litlogger/formats.py +9 -0
  11. webscout/Litlogger/handlers.py +18 -0
  12. webscout/Litlogger/logger.py +43 -1
  13. webscout/Provider/AISEARCH/genspark_search.py +7 -7
  14. webscout/Provider/AISEARCH/scira_search.py +3 -2
  15. webscout/Provider/GeminiProxy.py +140 -0
  16. webscout/Provider/LambdaChat.py +7 -1
  17. webscout/Provider/MCPCore.py +78 -75
  18. webscout/Provider/OPENAI/BLACKBOXAI.py +1046 -1017
  19. webscout/Provider/OPENAI/GeminiProxy.py +328 -0
  20. webscout/Provider/OPENAI/Qwen3.py +303 -303
  21. webscout/Provider/OPENAI/README.md +5 -0
  22. webscout/Provider/OPENAI/README_AUTOPROXY.md +238 -0
  23. webscout/Provider/OPENAI/TogetherAI.py +355 -0
  24. webscout/Provider/OPENAI/__init__.py +16 -1
  25. webscout/Provider/OPENAI/autoproxy.py +332 -0
  26. webscout/Provider/OPENAI/base.py +101 -14
  27. webscout/Provider/OPENAI/chatgpt.py +15 -2
  28. webscout/Provider/OPENAI/chatgptclone.py +14 -3
  29. webscout/Provider/OPENAI/deepinfra.py +339 -328
  30. webscout/Provider/OPENAI/e2b.py +295 -74
  31. webscout/Provider/OPENAI/mcpcore.py +109 -70
  32. webscout/Provider/OPENAI/opkfc.py +18 -6
  33. webscout/Provider/OPENAI/scirachat.py +59 -50
  34. webscout/Provider/OPENAI/toolbaz.py +2 -10
  35. webscout/Provider/OPENAI/writecream.py +166 -166
  36. webscout/Provider/OPENAI/x0gpt.py +367 -367
  37. webscout/Provider/OPENAI/xenai.py +514 -0
  38. webscout/Provider/OPENAI/yep.py +389 -383
  39. webscout/Provider/STT/__init__.py +3 -0
  40. webscout/Provider/STT/base.py +281 -0
  41. webscout/Provider/STT/elevenlabs.py +265 -0
  42. webscout/Provider/TTI/__init__.py +4 -1
  43. webscout/Provider/TTI/aiarta.py +399 -365
  44. webscout/Provider/TTI/base.py +74 -2
  45. webscout/Provider/TTI/bing.py +231 -0
  46. webscout/Provider/TTI/fastflux.py +63 -30
  47. webscout/Provider/TTI/gpt1image.py +149 -0
  48. webscout/Provider/TTI/imagen.py +196 -0
  49. webscout/Provider/TTI/magicstudio.py +60 -29
  50. webscout/Provider/TTI/piclumen.py +43 -32
  51. webscout/Provider/TTI/pixelmuse.py +232 -225
  52. webscout/Provider/TTI/pollinations.py +43 -32
  53. webscout/Provider/TTI/together.py +287 -0
  54. webscout/Provider/TTI/utils.py +2 -1
  55. webscout/Provider/TTS/README.md +1 -0
  56. webscout/Provider/TTS/__init__.py +2 -1
  57. webscout/Provider/TTS/freetts.py +140 -0
  58. webscout/Provider/TTS/speechma.py +45 -39
  59. webscout/Provider/TogetherAI.py +366 -0
  60. webscout/Provider/UNFINISHED/ChutesAI.py +314 -0
  61. webscout/Provider/UNFINISHED/fetch_together_models.py +95 -0
  62. webscout/Provider/XenAI.py +324 -0
  63. webscout/Provider/__init__.py +8 -0
  64. webscout/Provider/deepseek_assistant.py +378 -0
  65. webscout/Provider/scira_chat.py +3 -2
  66. webscout/Provider/toolbaz.py +0 -1
  67. webscout/auth/__init__.py +44 -0
  68. webscout/auth/api_key_manager.py +189 -0
  69. webscout/auth/auth_system.py +100 -0
  70. webscout/auth/config.py +76 -0
  71. webscout/auth/database.py +400 -0
  72. webscout/auth/exceptions.py +67 -0
  73. webscout/auth/middleware.py +248 -0
  74. webscout/auth/models.py +130 -0
  75. webscout/auth/providers.py +257 -0
  76. webscout/auth/rate_limiter.py +254 -0
  77. webscout/auth/request_models.py +127 -0
  78. webscout/auth/request_processing.py +226 -0
  79. webscout/auth/routes.py +526 -0
  80. webscout/auth/schemas.py +103 -0
  81. webscout/auth/server.py +312 -0
  82. webscout/auth/static/favicon.svg +11 -0
  83. webscout/auth/swagger_ui.py +203 -0
  84. webscout/auth/templates/components/authentication.html +237 -0
  85. webscout/auth/templates/components/base.html +103 -0
  86. webscout/auth/templates/components/endpoints.html +750 -0
  87. webscout/auth/templates/components/examples.html +491 -0
  88. webscout/auth/templates/components/footer.html +75 -0
  89. webscout/auth/templates/components/header.html +27 -0
  90. webscout/auth/templates/components/models.html +286 -0
  91. webscout/auth/templates/components/navigation.html +70 -0
  92. webscout/auth/templates/static/api.js +455 -0
  93. webscout/auth/templates/static/icons.js +168 -0
  94. webscout/auth/templates/static/main.js +784 -0
  95. webscout/auth/templates/static/particles.js +201 -0
  96. webscout/auth/templates/static/styles.css +3353 -0
  97. webscout/auth/templates/static/ui.js +374 -0
  98. webscout/auth/templates/swagger_ui.html +170 -0
  99. webscout/client.py +49 -3
  100. webscout/litagent/Readme.md +12 -3
  101. webscout/litagent/agent.py +99 -62
  102. webscout/scout/core/scout.py +104 -26
  103. webscout/scout/element.py +139 -18
  104. webscout/swiftcli/core/cli.py +14 -3
  105. webscout/swiftcli/decorators/output.py +59 -9
  106. webscout/update_checker.py +31 -49
  107. webscout/version.py +1 -1
  108. webscout/webscout_search.py +4 -12
  109. webscout/webscout_search_async.py +3 -10
  110. webscout/yep_search.py +2 -11
  111. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/METADATA +41 -11
  112. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/RECORD +116 -68
  113. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/entry_points.txt +1 -1
  114. webscout/Provider/HF_space/__init__.py +0 -0
  115. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  116. webscout/Provider/OPENAI/api.py +0 -1035
  117. webscout/Provider/TTI/artbit.py +0 -0
  118. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/WHEEL +0 -0
  119. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/licenses/LICENSE.md +0 -0
  120. {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,8 @@
1
1
  import time
2
2
  import uuid
3
3
  import json
4
+ import random
5
+ import string
4
6
  from typing import List, Dict, Optional, Union, Generator, Any
5
7
 
6
8
  # Use curl_cffi for requests
@@ -8,8 +10,8 @@ from curl_cffi.requests import Session
8
10
  from curl_cffi import CurlError
9
11
 
10
12
  # Import base classes and utility structures
11
- from .base import OpenAICompatibleProvider, BaseChat, BaseCompletions
12
- from .utils import (
13
+ from webscout.Provider.OPENAI.base import OpenAICompatibleProvider, BaseChat, BaseCompletions
14
+ from webscout.Provider.OPENAI.utils import (
13
15
  ChatCompletionChunk, ChatCompletion, Choice, ChoiceDelta,
14
16
  ChatCompletionMessage, CompletionUsage
15
17
  )
@@ -274,11 +276,8 @@ class MCPCore(OpenAICompatibleProvider):
274
276
  """
275
277
  OpenAI-compatible client for the MCPCore API (chat.mcpcore.xyz).
276
278
 
277
- Requires cookies to be stored in a JSON file (e.g., 'cookies.json').
278
- The JSON file should contain a list of cookie objects, including one named 'token'.
279
-
280
279
  Usage:
281
- client = MCPCore(cookies_path="path/to/your/cookies.json")
280
+ client = MCPCore()
282
281
  response = client.chat.completions.create(
283
282
  model="google/gemma-7b-it",
284
283
  messages=[{"role": "user", "content": "Hello!"}]
@@ -286,71 +285,96 @@ class MCPCore(OpenAICompatibleProvider):
286
285
  print(response.choices[0].message.content)
287
286
  """
288
287
  AVAILABLE_MODELS = [
289
- "google/gemma-7b-it",
290
- "deepseek-ai/deepseek-coder-33b-instruct",
291
- "deepseek-ai/DeepSeek-R1",
292
- "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B",
293
- "deepseek-ai/DeepSeek-v3-0324",
294
- "fixie-ai/ultravox-v0_4_1-llama-3_1-8b",
295
- "meta-llama/Llama-3.3-70B-Instruct",
296
- "meta-llama/Llama-4-Maverick-Instruct",
297
- "mistralai/Mistral-7B-Instruct-v0.2",
298
- "qwen-max-latest",
299
- "qwen-plus-latest",
300
- "qwen2.5-coder-32b-instruct",
301
- "qwen-turbo-latest",
302
- "qwen2.5-14b-instruct-1m",
303
- "GLM-4-32B",
304
- "Z1-32B",
305
- "Z1-Rumination",
306
- "arena-model",
307
- "qvq-72b-preview-0310",
308
- "qwq-32b",
309
- "qwen3-235b-a22b",
310
- "qwen3-30b-a3b",
311
- "qwen3-32b",
312
- "deepseek-flash",
313
- "@cf/meta/llama-4-scout-17b-16e-instruct",
314
- "任务专用",
288
+ "@cf/deepseek-ai/deepseek-math-7b-instruct",
289
+ "@cf/deepseek-ai/deepseek-r1-distill-qwen-32b",
290
+ "@cf/defog/sqlcoder-7b-2",
291
+ "@cf/fblgit/una-cybertron-7b-v2-bf16",
292
+ "@cf/google/gemma-3-12b-it",
293
+ "@cf/meta/llama-2-7b-chat-int8",
294
+ "@hf/thebloke/llama-2-13b-chat-awq",
295
+ "@hf/thebloke/llamaguard-7b-awq",
296
+ "@hf/thebloke/mistral-7b-instruct-v0.1-awq",
297
+ "@hf/thebloke/neural-chat-7b-v3-1-awq",
298
+ "anthropic/claude-3.5-haiku",
299
+ "anthropic/claude-3.5-sonnet",
300
+ "anthropic/claude-3.7-sonnet",
301
+ "anthropic/claude-3.7-sonnet:thinking",
302
+ "anthropic/claude-opus-4",
303
+ "anthropic/claude-sonnet-4",
304
+ "openai/chatgpt-4o-latest",
305
+ "openai/gpt-3.5-turbo",
306
+ "openai/gpt-4.1",
307
+ "openai/gpt-4.1-mini",
308
+ "openai/gpt-4.1-nano",
309
+ "openai/gpt-4o-mini-search-preview",
310
+ "openai/gpt-4o-search-preview",
311
+ "openai/o1-pro",
312
+ "openai/o3-mini",
313
+ "sarvam-m",
314
+ "x-ai/grok-3-beta",
315
315
  ]
316
316
 
317
+ def _auto_fetch_token(self):
318
+ """Automatically fetch a token from the signup endpoint."""
319
+ session = Session()
320
+ def random_string(length=8):
321
+ return ''.join(random.choices(string.ascii_lowercase, k=length))
322
+ name = random_string(6)
323
+ email = f"{random_string(8)}@gmail.com"
324
+ password = email
325
+ profile_image_url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAAkRJREFUeF7tmDFOw0AUBdcSiIaKM3CKHIQ7UHEISq5AiUTFHYC0XADoTRsJEZFEjhFIaYAim92fjGFS736/zOTZzjavl0d98oMh0CgE4+IriEJYPhQC86EQhdAIwPL4DFEIjAAsjg1RCIwALI4NUQiMACyODVEIjAAsjg1RCIwALI4NUQiMACyODVEIjAAsjg1RCIwALI4NUQiMACyODVEIjAAsjg1RCIwALI4NUQiMACyODVEIjAAsjg2BCfkAIqwAA94KZ/EAAAAASUVORK5CYII="
326
+ payload = {
327
+ "name": name,
328
+ "email": email,
329
+ "password": password,
330
+ "profile_image_url": profile_image_url
331
+ }
332
+ headers = {
333
+ **LitAgent().generate_fingerprint(),
334
+ 'origin': 'https://chat.mcpcore.xyz',
335
+ 'referer': 'https://chat.mcpcore.xyz/auth',
336
+ }
337
+ try:
338
+ resp = session.post(
339
+ "https://chat.mcpcore.xyz/api/v1/auths/signup",
340
+ headers=headers,
341
+ json=payload,
342
+ timeout=30,
343
+ impersonate="chrome110"
344
+ )
345
+ if resp.ok:
346
+ data = resp.json()
347
+ token = data.get("token")
348
+ if token:
349
+ return token
350
+ # fallback: try to get from set-cookie
351
+ set_cookie = resp.headers.get("set-cookie", "")
352
+ if "token=" in set_cookie:
353
+ return set_cookie.split("token=")[1].split(";")[0]
354
+ raise RuntimeError(f"Failed to auto-fetch token: {resp.status_code} {resp.text}")
355
+ except Exception as e:
356
+ raise RuntimeError(f"Token auto-fetch failed: {e}")
357
+
317
358
  def __init__(
318
359
  self,
319
- cookies_path: str, # Make cookies path mandatory for authentication
320
360
  timeout: int = 60,
321
361
  ):
322
362
  """
323
363
  Initializes the MCPCore OpenAI-compatible client.
324
364
 
325
365
  Args:
326
- cookies_path: Path to the JSON file containing cookies (must include 'token').
327
366
  timeout: Request timeout in seconds.
328
- proxies: Optional proxy configuration.
329
- system_prompt: Default system prompt to use if none is provided in messages.
330
367
  """
331
368
  self.api_endpoint = "https://chat.mcpcore.xyz/api/chat/completions"
332
369
  self.timeout = timeout
333
- self.cookies_path = cookies_path
334
-
335
- try:
336
- self.token = self._load_token_from_cookies()
337
- if not self.token:
338
- raise ValueError("Could not find 'token' cookie in the provided file.")
339
- except Exception as e:
340
- raise ValueError(f"Failed to load authentication token from cookies file '{cookies_path}': {e}") from e
341
-
370
+ self.token = self._auto_fetch_token()
342
371
  self.session = Session() # Use curl_cffi Session
343
372
 
344
373
  # Basic headers + Authorization
345
374
  self.headers = {
346
- 'authority': 'chat.mcpcore.xyz',
347
- 'accept': '*/*', # Accept anything, let the server decide
348
- 'accept-language': 'en-US,en;q=0.9',
349
- 'authorization': f'Bearer {self.token}',
350
- 'content-type': 'application/json',
375
+ **LitAgent().generate_fingerprint(),
351
376
  'origin': 'https://chat.mcpcore.xyz',
352
- 'referer': 'https://chat.mcpcore.xyz/',
353
- 'user-agent': LitAgent().random(), # Use LitAgent for User-Agent
377
+ 'referer': 'https://chat.mcpcore.xyz/auth',
354
378
  }
355
379
  # Add more headers mimicking browser behavior if needed, e.g., sec-ch-ua, etc.
356
380
  # Example:
@@ -366,27 +390,42 @@ class MCPCore(OpenAICompatibleProvider):
366
390
  self.session.headers.update(self.headers)
367
391
  self.chat = Chat(self) # Initialize chat interface
368
392
 
369
- def _load_token_from_cookies(self) -> Optional[str]:
370
- """Load the 'token' value from a JSON cookies file."""
371
- try:
372
- with open(self.cookies_path, "r") as f:
373
- cookies = json.load(f)
374
- # Find the cookie named 'token'
375
- token_cookie = next((cookie for cookie in cookies if cookie.get("name") == "token"), None)
376
- return token_cookie.get("value") if token_cookie else None
377
- except FileNotFoundError:
378
- print(f"{RED}Error: Cookies file not found at {self.cookies_path}!{RESET}")
379
- return None
380
- except json.JSONDecodeError:
381
- print(f"{RED}Error: Invalid JSON format in cookies file: {self.cookies_path}!{RESET}")
382
- return None
383
- except Exception as e:
384
- print(f"{RED}An unexpected error occurred loading cookies: {e}{RESET}")
385
- return None
386
-
387
393
  @property
388
394
  def models(self):
389
395
  class _ModelList:
390
396
  def list(inner_self):
391
397
  return type(self).AVAILABLE_MODELS
392
398
  return _ModelList()
399
+
400
+ if __name__ == "__main__":
401
+ print("-" * 100)
402
+ print(f"{'Model':<50} {'Status':<10} {'Response'}")
403
+ print("-" * 100)
404
+
405
+ test_prompt = "Say 'Hello' in one word"
406
+
407
+ client = MCPCore()
408
+ for model in client.models.list():
409
+ print(f"\rTesting {model}...", end="")
410
+ try:
411
+ presp = client.chat.completions.create(
412
+ model=model,
413
+ messages=[{"role": "user", "content": test_prompt}]
414
+ )
415
+ # Try to get the response text (truncate to 100 chars)
416
+ if hasattr(presp, "choices") and presp.choices and hasattr(presp.choices[0], "message"):
417
+ content = presp.choices[0].message.content or ""
418
+ clean_text = content.strip().encode('utf-8', errors='ignore').decode('utf-8')
419
+ display_text = clean_text[:100] + "..." if len(clean_text) > 100 else clean_text
420
+ status = "✓" if clean_text else "✗"
421
+ if not clean_text:
422
+ display_text = "Empty or invalid response"
423
+ else:
424
+ status = "✗"
425
+ display_text = "Empty or invalid response"
426
+ print(f"\r{model:<50} {status:<10} {display_text}")
427
+ except Exception as e:
428
+ error_msg = str(e)
429
+ if len(error_msg) > 100:
430
+ error_msg = error_msg[:97] + "..."
431
+ print(f"\r{model:<50} {'✗':<10} Error: {error_msg}")
@@ -1,3 +1,4 @@
1
+ from datetime import datetime
1
2
  import time
2
3
  import uuid
3
4
  import requests
@@ -6,12 +7,12 @@ import random
6
7
  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 (
10
+ from webscout.Provider.OPENAI.base import OpenAICompatibleProvider, BaseChat, BaseCompletions
11
+ from webscout.Provider.OPENAI.utils import (
11
12
  ChatCompletionChunk, ChatCompletion, Choice, ChoiceDelta,
12
13
  ChatCompletionMessage, CompletionUsage, count_tokens
13
14
  )
14
-
15
+ from webscout.litagent import LitAgent
15
16
  # ANSI escape codes for formatting
16
17
  BOLD = "\033[1m"
17
18
  RED = "\033[91m"
@@ -466,7 +467,9 @@ class OPKFC(OpenAICompatibleProvider):
466
467
  "auto",
467
468
  "o4-mini",
468
469
  "gpt-4o-mini",
469
- "gpt-4o"
470
+ "gpt-4o",
471
+ "gpt-4-1-mini",
472
+
470
473
  ]
471
474
 
472
475
  def __init__(
@@ -491,10 +494,10 @@ class OPKFC(OpenAICompatibleProvider):
491
494
  self.session.proxies.update(proxies)
492
495
 
493
496
  # Set the user agent to match the original script
494
- self.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0"
497
+ self.user_agent = LitAgent().random()
495
498
 
496
499
  # Set the cookie from the original script
497
- self.cookie = "__vtins__KUc0LhjVWFNXQv11=%7B%22sid%22%3A%20%228fab09e3-c23e-5f60-b369-9697fbb821ce%22%2C%20%22vd%22%3A%201%2C%20%22stt%22%3A%200%2C%20%22dr%22%3A%200%2C%20%22expires%22%3A%201744896723481%2C%20%22ct%22%3A%201744894923481%7D; __51uvsct__KUc0LhjVWFNXQv11=1; __51vcke__KUc0LhjVWFNXQv11=06da852c-bb56-547c-91a8-43a0d485ffed; __51vuft__KUc0LhjVWFNXQv11=1744894923504; gfsessionid=1ochrgv17vy4sbd98xmwt6crpmkxwlqf; oai-nav-state=1; p_uv_id=ad86646801bc60d6d95f6098e4ee7450; _dd_s=rum=0&expire=1744895920821&logs=1&id=a39221c9-e8ed-44e6-a2c8-03192699c71e&created=1744894970625"
500
+ self.cookie = f"__vtins__KUc0LhjVWFNXQv11=%7B%22sid%22%3A%20%{uuid.uuid4().hex}%22%2C%20%22vd%22%3A%201%2C%20%22stt%22%3A%200%2C%20%22dr%22%3A%200%2C%20%22expires%22%3A%201744896723481%2C%20%22ct%22%3A%201744894923481%7D; __51uvsct__KUc0LhjVWFNXQv11=1; __51vcke__KUc0LhjVWFNXQv11=06da852c-bb56-547c-91a8-43a0d485ffed; __51vuft__KUc0LhjVWFNXQv11=1744894923504; gfsessionid=1ochrgv17vy4sbd98xmwt6crpmkxwlqf; oai-nav-state=1; p_uv_id=ad86646801bc60d6d95f6098e4ee7450; _dd_s=rum=0&expire=1744895920821&logs=1&id={uuid.uuid4().hex}&created={int(datetime.utcnow().timestamp() * 1000)}"
498
501
 
499
502
  # Initialize chat interface
500
503
  self.chat = Chat(self)
@@ -505,3 +508,12 @@ class OPKFC(OpenAICompatibleProvider):
505
508
  def list(inner_self):
506
509
  return type(self).AVAILABLE_MODELS
507
510
  return _ModelList()
511
+
512
+ if __name__ == "__main__":
513
+ # Example usage
514
+ client = OPKFC()
515
+ response = client.chat.completions.create(
516
+ model="auto",
517
+ messages=[{"role": "user", "content": "Hello!"}]
518
+ )
519
+ print(response.choices[0].message.content)
@@ -6,8 +6,8 @@ import re
6
6
  from typing import List, Dict, Optional, Union, Generator, Any
7
7
 
8
8
  # Import base classes and utility structures
9
- from .base import OpenAICompatibleProvider, BaseChat, BaseCompletions
10
- from .utils import (
9
+ from webscout.Provider.OPENAI.base import OpenAICompatibleProvider, BaseChat, BaseCompletions
10
+ from webscout.Provider.OPENAI.utils import (
11
11
  ChatCompletionChunk, ChatCompletion, Choice, ChoiceDelta,
12
12
  ChatCompletionMessage, CompletionUsage, get_system_prompt, count_tokens
13
13
  )
@@ -16,20 +16,7 @@ from .utils import (
16
16
  try:
17
17
  from webscout.litagent import LitAgent
18
18
  except ImportError:
19
- # Define a dummy LitAgent if webscout is not installed or accessible
20
- class LitAgent:
21
- def generate_fingerprint(self, browser: str = "chrome") -> Dict[str, Any]:
22
- # Return minimal default headers if LitAgent is unavailable
23
- print("Warning: LitAgent not found. Using default minimal headers.")
24
- return {
25
- "accept": "*/*",
26
- "accept_language": "en-US,en;q=0.9",
27
- "platform": "Windows",
28
- "sec_ch_ua": '"Not/A)Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
29
- "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
30
- "browser_type": browser,
31
- }
32
-
19
+ pass
33
20
  # --- SciraChat Client ---
34
21
 
35
22
  class Completions(BaseCompletions):
@@ -334,20 +321,37 @@ class SciraChat(OpenAICompatibleProvider):
334
321
  messages=[{"role": "user", "content": "Hello!"}]
335
322
  )
336
323
  """
337
-
338
- AVAILABLE_MODELS = {
339
- "scira-default": "Grok3-mini", # thinking model
340
- "scira-grok-3": "Grok3",
341
- "scira-anthropic": "Sonnet 3.7 thinking",
342
- "scira-vision" : "Grok2-Vision", # vision model
343
- "scira-4o": "GPT4o",
344
- "scira-qwq": "QWQ-32B",
345
- "scira-o4-mini": "o4-mini",
346
- "scira-google": "gemini 2.5 flash",
347
- "scira-google-pro": "gemini 2.5 pro",
348
- "scira-llama-4": "llama 4 Maverick",
324
+ # List of model display names for registration (aliases)
325
+ AVAILABLE_MODELS = [
326
+ "Grok3-mini (thinking)",
327
+ "Grok3",
328
+ "Claude 4 Sonnet",
329
+ "Claude 4 Sonnet Thinking",
330
+ "Grok2-Vision (vision)",
331
+ "GPT4o",
332
+ "QWQ-32B",
333
+ "o4-mini",
334
+ "Gemini 2.5 Flash Thinking",
335
+ "Gemini 2.5 Pro",
336
+ "Llama 4 Maverick",
337
+ ]
338
+ # Mapping from display name to internal model key
339
+ MODEL_NAME_MAP = {
340
+ "Grok3-mini (thinking)": "scira-default",
341
+ "Grok3": "scira-grok-3",
342
+ "Claude 4 Sonnet": "scira-anthropic",
343
+ "Claude 4 Sonnet Thinking": "scira-anthropic-thinking",
344
+ "Grok2-Vision (vision)": "scira-vision",
345
+ "GPT4o": "scira-4o",
346
+ "QWQ-32B": "scira-qwq",
347
+ "o4-mini": "scira-o4-mini",
348
+ "Gemini 2.5 Flash Thinking": "scira-google",
349
+ "Gemini 2.5 Pro": "scira-google-pro",
350
+ "Llama 4 Maverick": "scira-llama-4",
349
351
  }
350
-
352
+ # Optional: pretty display names for UI (reverse mapping)
353
+ MODEL_DISPLAY_NAMES = {v: k for k, v in MODEL_NAME_MAP.items()}
354
+
351
355
  def __init__(
352
356
  self,
353
357
  timeout: Optional[int] = None,
@@ -370,19 +374,9 @@ class SciraChat(OpenAICompatibleProvider):
370
374
 
371
375
  # Use the fingerprint for headers
372
376
  self.headers = {
373
- "Accept": self.fingerprint["accept"],
374
- "Accept-Encoding": "gzip, deflate, br, zstd",
375
- "Accept-Language": self.fingerprint["accept_language"],
376
- "Content-Type": "application/json",
377
+ **self.fingerprint,
377
378
  "Origin": "https://scira.ai",
378
379
  "Referer": "https://scira.ai/",
379
- "Sec-CH-UA": self.fingerprint["sec_ch_ua"] or '"Not)A;Brand";v="99", "Microsoft Edge";v="127", "Chromium";v="127"',
380
- "Sec-CH-UA-Mobile": "?0",
381
- "Sec-CH-UA-Platform": f'"{self.fingerprint["platform"]}"',
382
- "User-Agent": self.fingerprint["user_agent"],
383
- "Sec-Fetch-Dest": "empty",
384
- "Sec-Fetch-Mode": "cors",
385
- "Sec-Fetch-Site": "same-origin"
386
380
  }
387
381
 
388
382
  self.session.headers.update(self.headers)
@@ -406,11 +400,7 @@ class SciraChat(OpenAICompatibleProvider):
406
400
 
407
401
  # Update headers with new fingerprint
408
402
  self.headers.update({
409
- "Accept": self.fingerprint["accept"],
410
- "Accept-Language": self.fingerprint["accept_language"],
411
- "Sec-CH-UA": self.fingerprint["sec_ch_ua"] or self.headers["Sec-CH-UA"],
412
- "Sec-CH-UA-Platform": f'"{self.fingerprint["platform"]}"',
413
- "User-Agent": self.fingerprint["user_agent"],
403
+ **self.fingerprint,
414
404
  })
415
405
 
416
406
  # Update session headers
@@ -459,18 +449,20 @@ class SciraChat(OpenAICompatibleProvider):
459
449
 
460
450
  def convert_model_name(self, model: str) -> str:
461
451
  """
462
- Convert model names to ones supported by SciraChat.
452
+ Convert model display names or internal keys to ones supported by SciraChat.
463
453
 
464
454
  Args:
465
- model: Model name to convert
455
+ model: Model name or alias to convert
466
456
 
467
457
  Returns:
468
458
  SciraChat model name
469
459
  """
470
- # If the model is already a valid SciraChat model, return it
471
- if model in self.AVAILABLE_MODELS:
460
+ # If model is a display name (alias), map to internal key
461
+ if model in self.MODEL_NAME_MAP:
462
+ return self.MODEL_NAME_MAP[model]
463
+ # If model is already an internal key, return it if valid
464
+ if model in self.MODEL_DISPLAY_NAMES:
472
465
  return model
473
-
474
466
  # Default to scira-default if model not found
475
467
  print(f"Warning: Unknown model '{model}'. Using 'scira-default' instead.")
476
468
  return "scira-default"
@@ -479,5 +471,22 @@ class SciraChat(OpenAICompatibleProvider):
479
471
  def models(self):
480
472
  class _ModelList:
481
473
  def list(inner_self):
474
+ # Return display names (aliases)
482
475
  return type(self).AVAILABLE_MODELS
483
476
  return _ModelList()
477
+
478
+ if __name__ == "__main__":
479
+ ai = SciraChat()
480
+ response = ai.chat.completions.create(
481
+ model="Gemini 2.5 Pro",
482
+ messages=[
483
+ {"role": "user", "content": "who is pm of india?"}
484
+ ],
485
+ stream=True
486
+ )
487
+ for chunk in response:
488
+ if hasattr(chunk, "choices") and chunk.choices and hasattr(chunk.choices[0], "delta"):
489
+ content = getattr(chunk.choices[0].delta, "content", None)
490
+ if content:
491
+ print(content, end="", flush=True)
492
+ print()
@@ -302,7 +302,6 @@ class Toolbaz(OpenAICompatibleProvider):
302
302
  "Llama-4-Scout",
303
303
  "Llama-3.3-70B",
304
304
  "Qwen2.5-72B",
305
- "Qwen2-72B",
306
305
  "grok-2-1212",
307
306
  "grok-3-beta",
308
307
  "toolbaz_v3.5_pro",
@@ -338,18 +337,11 @@ class Toolbaz(OpenAICompatibleProvider):
338
337
 
339
338
  # Set up headers
340
339
  self.session.headers.update({
341
- "user-agent": LitAgent().generate_fingerprint(browser=browser)["user_agent"],
342
- "accept": "*/*",
343
- "accept-language": "en-US",
344
- "cache-control": "no-cache",
345
- "connection": "keep-alive",
346
- "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
347
- "origin": "https://toolbaz.com",
340
+ **LitAgent().generate_fingerprint(browser=browser),
348
341
  "pragma": "no-cache",
349
342
  "referer": "https://toolbaz.com/",
350
- "sec-fetch-mode": "cors"
351
343
  })
352
-
344
+
353
345
  # Initialize chat property
354
346
  self.chat = Chat(self)
355
347