webscout 8.3.1__py3-none-any.whl → 8.3.3__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 (114) hide show
  1. webscout/AIutel.py +180 -78
  2. webscout/Bing_search.py +417 -0
  3. webscout/Extra/gguf.py +706 -177
  4. webscout/Provider/AISEARCH/__init__.py +1 -0
  5. webscout/Provider/AISEARCH/genspark_search.py +7 -7
  6. webscout/Provider/AISEARCH/stellar_search.py +132 -0
  7. webscout/Provider/ExaChat.py +84 -58
  8. webscout/Provider/GeminiProxy.py +140 -0
  9. webscout/Provider/HeckAI.py +85 -80
  10. webscout/Provider/Jadve.py +56 -50
  11. webscout/Provider/MCPCore.py +78 -75
  12. webscout/Provider/MiniMax.py +207 -0
  13. webscout/Provider/Nemotron.py +41 -13
  14. webscout/Provider/Netwrck.py +34 -51
  15. webscout/Provider/OPENAI/BLACKBOXAI.py +0 -4
  16. webscout/Provider/OPENAI/GeminiProxy.py +328 -0
  17. webscout/Provider/OPENAI/MiniMax.py +298 -0
  18. webscout/Provider/OPENAI/README.md +32 -29
  19. webscout/Provider/OPENAI/README_AUTOPROXY.md +238 -0
  20. webscout/Provider/OPENAI/TogetherAI.py +4 -17
  21. webscout/Provider/OPENAI/__init__.py +17 -1
  22. webscout/Provider/OPENAI/autoproxy.py +1067 -39
  23. webscout/Provider/OPENAI/base.py +17 -76
  24. webscout/Provider/OPENAI/deepinfra.py +42 -108
  25. webscout/Provider/OPENAI/e2b.py +0 -1
  26. webscout/Provider/OPENAI/flowith.py +179 -166
  27. webscout/Provider/OPENAI/friendli.py +233 -0
  28. webscout/Provider/OPENAI/mcpcore.py +109 -70
  29. webscout/Provider/OPENAI/monochat.py +329 -0
  30. webscout/Provider/OPENAI/pydantic_imports.py +1 -172
  31. webscout/Provider/OPENAI/scirachat.py +59 -51
  32. webscout/Provider/OPENAI/toolbaz.py +3 -9
  33. webscout/Provider/OPENAI/typegpt.py +1 -1
  34. webscout/Provider/OPENAI/utils.py +19 -42
  35. webscout/Provider/OPENAI/x0gpt.py +14 -2
  36. webscout/Provider/OPENAI/xenai.py +514 -0
  37. webscout/Provider/OPENAI/yep.py +8 -2
  38. webscout/Provider/OpenGPT.py +54 -32
  39. webscout/Provider/PI.py +58 -84
  40. webscout/Provider/StandardInput.py +32 -13
  41. webscout/Provider/TTI/README.md +9 -9
  42. webscout/Provider/TTI/__init__.py +3 -1
  43. webscout/Provider/TTI/aiarta.py +92 -78
  44. webscout/Provider/TTI/bing.py +231 -0
  45. webscout/Provider/TTI/infip.py +212 -0
  46. webscout/Provider/TTI/monochat.py +220 -0
  47. webscout/Provider/TTS/speechma.py +45 -39
  48. webscout/Provider/TeachAnything.py +11 -3
  49. webscout/Provider/TextPollinationsAI.py +78 -70
  50. webscout/Provider/TogetherAI.py +350 -0
  51. webscout/Provider/Venice.py +37 -46
  52. webscout/Provider/VercelAI.py +27 -24
  53. webscout/Provider/WiseCat.py +35 -35
  54. webscout/Provider/WrDoChat.py +22 -26
  55. webscout/Provider/WritingMate.py +26 -22
  56. webscout/Provider/XenAI.py +324 -0
  57. webscout/Provider/__init__.py +10 -5
  58. webscout/Provider/deepseek_assistant.py +378 -0
  59. webscout/Provider/granite.py +48 -57
  60. webscout/Provider/koala.py +51 -39
  61. webscout/Provider/learnfastai.py +49 -64
  62. webscout/Provider/llmchat.py +79 -93
  63. webscout/Provider/llmchatco.py +63 -78
  64. webscout/Provider/multichat.py +51 -40
  65. webscout/Provider/oivscode.py +1 -1
  66. webscout/Provider/scira_chat.py +159 -96
  67. webscout/Provider/scnet.py +13 -13
  68. webscout/Provider/searchchat.py +13 -13
  69. webscout/Provider/sonus.py +12 -11
  70. webscout/Provider/toolbaz.py +25 -8
  71. webscout/Provider/turboseek.py +41 -42
  72. webscout/Provider/typefully.py +27 -12
  73. webscout/Provider/typegpt.py +41 -46
  74. webscout/Provider/uncovr.py +55 -90
  75. webscout/Provider/x0gpt.py +33 -17
  76. webscout/Provider/yep.py +79 -96
  77. webscout/auth/__init__.py +55 -0
  78. webscout/auth/api_key_manager.py +189 -0
  79. webscout/auth/auth_system.py +100 -0
  80. webscout/auth/config.py +76 -0
  81. webscout/auth/database.py +400 -0
  82. webscout/auth/exceptions.py +67 -0
  83. webscout/auth/middleware.py +248 -0
  84. webscout/auth/models.py +130 -0
  85. webscout/auth/providers.py +279 -0
  86. webscout/auth/rate_limiter.py +254 -0
  87. webscout/auth/request_models.py +127 -0
  88. webscout/auth/request_processing.py +226 -0
  89. webscout/auth/routes.py +550 -0
  90. webscout/auth/schemas.py +103 -0
  91. webscout/auth/server.py +367 -0
  92. webscout/client.py +121 -70
  93. webscout/litagent/Readme.md +68 -55
  94. webscout/litagent/agent.py +99 -9
  95. webscout/scout/core/scout.py +104 -26
  96. webscout/scout/element.py +139 -18
  97. webscout/swiftcli/core/cli.py +14 -3
  98. webscout/swiftcli/decorators/output.py +59 -9
  99. webscout/update_checker.py +31 -49
  100. webscout/version.py +1 -1
  101. webscout/webscout_search.py +4 -12
  102. webscout/webscout_search_async.py +3 -10
  103. webscout/yep_search.py +2 -11
  104. {webscout-8.3.1.dist-info → webscout-8.3.3.dist-info}/METADATA +141 -99
  105. {webscout-8.3.1.dist-info → webscout-8.3.3.dist-info}/RECORD +109 -83
  106. {webscout-8.3.1.dist-info → webscout-8.3.3.dist-info}/entry_points.txt +1 -1
  107. webscout/Provider/HF_space/__init__.py +0 -0
  108. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  109. webscout/Provider/OPENAI/api.py +0 -1320
  110. webscout/Provider/TTI/fastflux.py +0 -233
  111. webscout/Provider/Writecream.py +0 -246
  112. {webscout-8.3.1.dist-info → webscout-8.3.3.dist-info}/WHEEL +0 -0
  113. {webscout-8.3.1.dist-info → webscout-8.3.3.dist-info}/licenses/LICENSE.md +0 -0
  114. {webscout-8.3.1.dist-info → webscout-8.3.3.dist-info}/top_level.txt +0 -0
@@ -1,172 +1 @@
1
- from pydantic import (
2
- # dataclasses
3
- dataclasses,
4
- # functional validators
5
- field_validator,
6
- model_validator,
7
- AfterValidator,
8
- BeforeValidator,
9
- PlainValidator,
10
- WrapValidator,
11
- SkipValidation,
12
- InstanceOf,
13
- ModelWrapValidatorHandler,
14
- # JSON Schema
15
- WithJsonSchema,
16
- # deprecated V1 functional validators
17
- root_validator,
18
- validator,
19
- # functional serializers
20
- field_serializer,
21
- model_serializer,
22
- PlainSerializer,
23
- SerializeAsAny,
24
- WrapSerializer,
25
- # config
26
- ConfigDict,
27
- with_config,
28
- # deprecated V1 config
29
- BaseConfig,
30
- Extra,
31
- # validate_call
32
- validate_call,
33
- # errors
34
- PydanticErrorCodes,
35
- PydanticUserError,
36
- PydanticSchemaGenerationError,
37
- PydanticImportError,
38
- PydanticUndefinedAnnotation,
39
- PydanticInvalidForJsonSchema,
40
- PydanticForbiddenQualifier,
41
- # fields
42
- Field,
43
- computed_field,
44
- PrivateAttr,
45
- # alias
46
- AliasChoices,
47
- AliasGenerator,
48
- AliasPath,
49
- # main
50
- BaseModel,
51
- create_model,
52
- # network
53
- AnyUrl,
54
- AnyHttpUrl,
55
- FileUrl,
56
- HttpUrl,
57
- FtpUrl,
58
- WebsocketUrl,
59
- AnyWebsocketUrl,
60
- UrlConstraints,
61
- EmailStr,
62
- NameEmail,
63
- IPvAnyAddress,
64
- IPvAnyInterface,
65
- IPvAnyNetwork,
66
- PostgresDsn,
67
- CockroachDsn,
68
- AmqpDsn,
69
- RedisDsn,
70
- MongoDsn,
71
- KafkaDsn,
72
- NatsDsn,
73
- MySQLDsn,
74
- MariaDBDsn,
75
- ClickHouseDsn,
76
- SnowflakeDsn,
77
- validate_email,
78
- # root_model
79
- RootModel,
80
- # deprecated tools
81
- parse_obj_as,
82
- schema_of,
83
- schema_json_of,
84
- # types
85
- Strict,
86
- StrictStr,
87
- conbytes,
88
- conlist,
89
- conset,
90
- confrozenset,
91
- constr,
92
- StringConstraints,
93
- ImportString,
94
- conint,
95
- PositiveInt,
96
- NegativeInt,
97
- NonNegativeInt,
98
- NonPositiveInt,
99
- confloat,
100
- PositiveFloat,
101
- NegativeFloat,
102
- NonNegativeFloat,
103
- NonPositiveFloat,
104
- FiniteFloat,
105
- condecimal,
106
- condate,
107
- UUID1,
108
- UUID3,
109
- UUID4,
110
- UUID5,
111
- UUID6,
112
- UUID7,
113
- UUID8,
114
- FilePath,
115
- DirectoryPath,
116
- NewPath,
117
- Json,
118
- Secret,
119
- SecretStr,
120
- SecretBytes,
121
- SocketPath,
122
- StrictBool,
123
- StrictBytes,
124
- StrictInt,
125
- StrictFloat,
126
- PaymentCardNumber,
127
- ByteSize,
128
- PastDate,
129
- FutureDate,
130
- PastDatetime,
131
- FutureDatetime,
132
- AwareDatetime,
133
- NaiveDatetime,
134
- AllowInfNan,
135
- EncoderProtocol,
136
- EncodedBytes,
137
- EncodedStr,
138
- Base64Encoder,
139
- Base64Bytes,
140
- Base64Str,
141
- Base64UrlBytes,
142
- Base64UrlStr,
143
- GetPydanticSchema,
144
- Tag,
145
- Discriminator,
146
- JsonValue,
147
- FailFast,
148
- # type_adapter
149
- TypeAdapter,
150
- # version
151
- __version__,
152
- VERSION,
153
- # warnings
154
- PydanticDeprecatedSince20,
155
- PydanticDeprecatedSince26,
156
- PydanticDeprecatedSince29,
157
- PydanticDeprecatedSince210,
158
- PydanticDeprecatedSince211,
159
- PydanticDeprecationWarning,
160
- PydanticExperimentalWarning,
161
- # annotated handlers
162
- GetCoreSchemaHandler,
163
- GetJsonSchemaHandler,
164
- # pydantic_core
165
- ValidationError,
166
- ValidationInfo,
167
- SerializationInfo,
168
- ValidatorFunctionWrapHandler,
169
- FieldSerializationInfo,
170
- SerializerFunctionWrapHandler,
171
- OnErrorOmit,
172
- )
1
+ from pydantic import *
@@ -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,21 +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": "Claude 4 Sonnet",
342
- "scira-anthropic-thinking": "Claude 4 Sonnet Thinking", # thinking model
343
- "scira-vision" : "Grok2-Vision", # vision model
344
- "scira-4o": "GPT4o",
345
- "scira-qwq": "QWQ-32B",
346
- "scira-o4-mini": "o4-mini",
347
- "scira-google": "gemini 2.5 flash Thinking", # thinking model
348
- "scira-google-pro": "gemini 2.5 pro",
349
- "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",
350
351
  }
351
-
352
+ # Optional: pretty display names for UI (reverse mapping)
353
+ MODEL_DISPLAY_NAMES = {v: k for k, v in MODEL_NAME_MAP.items()}
354
+
352
355
  def __init__(
353
356
  self,
354
357
  timeout: Optional[int] = None,
@@ -371,19 +374,9 @@ class SciraChat(OpenAICompatibleProvider):
371
374
 
372
375
  # Use the fingerprint for headers
373
376
  self.headers = {
374
- "Accept": self.fingerprint["accept"],
375
- "Accept-Encoding": "gzip, deflate, br, zstd",
376
- "Accept-Language": self.fingerprint["accept_language"],
377
- "Content-Type": "application/json",
377
+ **self.fingerprint,
378
378
  "Origin": "https://scira.ai",
379
379
  "Referer": "https://scira.ai/",
380
- "Sec-CH-UA": self.fingerprint["sec_ch_ua"] or '"Not)A;Brand";v="99", "Microsoft Edge";v="127", "Chromium";v="127"',
381
- "Sec-CH-UA-Mobile": "?0",
382
- "Sec-CH-UA-Platform": f'"{self.fingerprint["platform"]}"',
383
- "User-Agent": self.fingerprint["user_agent"],
384
- "Sec-Fetch-Dest": "empty",
385
- "Sec-Fetch-Mode": "cors",
386
- "Sec-Fetch-Site": "same-origin"
387
380
  }
388
381
 
389
382
  self.session.headers.update(self.headers)
@@ -407,11 +400,7 @@ class SciraChat(OpenAICompatibleProvider):
407
400
 
408
401
  # Update headers with new fingerprint
409
402
  self.headers.update({
410
- "Accept": self.fingerprint["accept"],
411
- "Accept-Language": self.fingerprint["accept_language"],
412
- "Sec-CH-UA": self.fingerprint["sec_ch_ua"] or self.headers["Sec-CH-UA"],
413
- "Sec-CH-UA-Platform": f'"{self.fingerprint["platform"]}"',
414
- "User-Agent": self.fingerprint["user_agent"],
403
+ **self.fingerprint,
415
404
  })
416
405
 
417
406
  # Update session headers
@@ -460,18 +449,20 @@ class SciraChat(OpenAICompatibleProvider):
460
449
 
461
450
  def convert_model_name(self, model: str) -> str:
462
451
  """
463
- Convert model names to ones supported by SciraChat.
452
+ Convert model display names or internal keys to ones supported by SciraChat.
464
453
 
465
454
  Args:
466
- model: Model name to convert
455
+ model: Model name or alias to convert
467
456
 
468
457
  Returns:
469
458
  SciraChat model name
470
459
  """
471
- # If the model is already a valid SciraChat model, return it
472
- 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:
473
465
  return model
474
-
475
466
  # Default to scira-default if model not found
476
467
  print(f"Warning: Unknown model '{model}'. Using 'scira-default' instead.")
477
468
  return "scira-default"
@@ -480,5 +471,22 @@ class SciraChat(OpenAICompatibleProvider):
480
471
  def models(self):
481
472
  class _ModelList:
482
473
  def list(inner_self):
474
+ # Return display names (aliases)
483
475
  return type(self).AVAILABLE_MODELS
484
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()
@@ -292,6 +292,7 @@ class Toolbaz(OpenAICompatibleProvider):
292
292
  AVAILABLE_MODELS = [
293
293
  "gemini-2.5-flash",
294
294
  "gemini-2.0-flash-thinking",
295
+ "sonar",
295
296
  "gemini-2.0-flash",
296
297
  "gemini-1.5-flash",
297
298
  "o3-mini",
@@ -337,18 +338,11 @@ class Toolbaz(OpenAICompatibleProvider):
337
338
 
338
339
  # Set up headers
339
340
  self.session.headers.update({
340
- "user-agent": LitAgent().generate_fingerprint(browser=browser)["user_agent"],
341
- "accept": "*/*",
342
- "accept-language": "en-US",
343
- "cache-control": "no-cache",
344
- "connection": "keep-alive",
345
- "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
346
- "origin": "https://toolbaz.com",
341
+ **LitAgent().generate_fingerprint(browser=browser),
347
342
  "pragma": "no-cache",
348
343
  "referer": "https://toolbaz.com/",
349
- "sec-fetch-mode": "cors"
350
344
  })
351
-
345
+
352
346
  # Initialize chat property
353
347
  self.chat = Chat(self)
354
348
 
@@ -286,7 +286,7 @@ class TypeGPT(OpenAICompatibleProvider):
286
286
 
287
287
  AVAILABLE_MODELS = [
288
288
  # Working Models (based on testing)
289
- "gpt-4o-mini-2024-07-18",
289
+ "gpt-4o-mini",
290
290
  "chatgpt-4o-latest",
291
291
  "deepseek-r1",
292
292
  "deepseek-v3",
@@ -1,10 +1,9 @@
1
- from typing import List, Dict, Optional, Any, Union, Literal
1
+ from typing import List, Dict, Optional, Any
2
2
  from enum import Enum
3
3
  import time
4
4
  import uuid
5
5
  from webscout.Provider.OPENAI.pydantic_imports import (
6
- BaseModel, Field, field_validator, model_validator, field_serializer, model_serializer,
7
- StrictStr, StrictInt, StrictFloat, StrictBool
6
+ BaseModel, Field, StrictStr, StrictInt
8
7
  )
9
8
 
10
9
  # --- OpenAI Response Structure Mimics ---
@@ -270,49 +269,27 @@ def get_last_user_message(messages: List[Dict[str, Any]]) -> str:
270
269
 
271
270
  def count_tokens(text_or_messages: Any) -> int:
272
271
  """
273
- Count tokens in a string or a list of messages using tiktoken if available, else fallback to webstoken's WordTokenizer.
272
+ Count tokens in a string or a list of messages using tiktoken.
274
273
 
275
274
  Args:
276
275
  text_or_messages: A string or a list of messages (string or any type).
277
- model: Optional model name for tiktoken encoding.
278
276
 
279
277
  Returns:
280
278
  int: Number of tokens.
281
279
  """
282
- try:
283
- import tiktoken
284
- # Use tiktoken if available
285
- if isinstance(text_or_messages, str):
286
- enc = tiktoken.encoding_for_model("gpt-4o")
287
- return len(enc.encode(text_or_messages))
288
- elif isinstance(text_or_messages, list):
289
- enc = tiktoken.encoding_for_model("gpt-4o")
290
- total = 0
291
- for m in text_or_messages:
292
- # Remove .get('content', '') and treat m as string or convert to string
293
- if isinstance(m, str):
294
- total += len(enc.encode(m))
295
- else:
296
- total += len(enc.encode(str(m)))
297
- return total
298
- else:
299
- return 0
300
- except ImportError:
301
- # Fallback to webstoken's WordTokenizer
302
- try:
303
- from webstoken import WordTokenizer
304
- except ImportError:
305
- return 0
306
- tokenizer = WordTokenizer()
307
- if isinstance(text_or_messages, str):
308
- return len(tokenizer.tokenize(text_or_messages))
309
- elif isinstance(text_or_messages, list):
310
- total = 0
311
- for m in text_or_messages:
312
- if isinstance(m, str):
313
- total += len(tokenizer.tokenize(m))
314
- else:
315
- total += len(tokenizer.tokenize(str(m)))
316
- return total
317
- else:
318
- return 0
280
+ import tiktoken
281
+ if isinstance(text_or_messages, str):
282
+ enc = tiktoken.encoding_for_model("gpt-4o")
283
+ return len(enc.encode(text_or_messages))
284
+ elif isinstance(text_or_messages, list):
285
+ enc = tiktoken.encoding_for_model("gpt-4o")
286
+ total = 0
287
+ for m in text_or_messages:
288
+ if isinstance(m, str):
289
+ total += len(enc.encode(m))
290
+ else:
291
+ total += len(enc.encode(str(m)))
292
+ return total
293
+ else:
294
+ return 0
295
+
@@ -6,8 +6,8 @@ import json
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, count_tokens
13
13
  )
@@ -365,3 +365,15 @@ class X0GPT(OpenAICompatibleProvider):
365
365
  """
366
366
  # X0GPT doesn't actually use model names, but we'll keep this for compatibility
367
367
  return model
368
+
369
+ if __name__ == "__main__":
370
+ from rich import print
371
+ client = X0GPT()
372
+ response = client.chat.completions.create(
373
+ model="X0GPT",
374
+ messages=[{"role": "user", "content": "Hello!"}],
375
+ stream=True
376
+ )
377
+
378
+ for chunk in response:
379
+ print(chunk, end='', flush=True)