webscout 8.2.2__py3-none-any.whl → 8.2.7__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 (306) hide show
  1. webscout/AIauto.py +112 -22
  2. webscout/AIbase.py +144 -7
  3. webscout/AIutel.py +249 -131
  4. webscout/Bard.py +579 -206
  5. webscout/DWEBS.py +78 -35
  6. webscout/__init__.py +0 -1
  7. webscout/cli.py +256 -0
  8. webscout/conversation.py +307 -436
  9. webscout/exceptions.py +23 -0
  10. webscout/prompt_manager.py +56 -42
  11. webscout/version.py +1 -1
  12. webscout/webscout_search.py +65 -47
  13. webscout/webscout_search_async.py +81 -126
  14. webscout/yep_search.py +93 -43
  15. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info}/METADATA +172 -52
  16. webscout-8.2.7.dist-info/RECORD +26 -0
  17. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info}/WHEEL +1 -1
  18. webscout-8.2.7.dist-info/entry_points.txt +3 -0
  19. webscout-8.2.7.dist-info/top_level.txt +1 -0
  20. inferno/__init__.py +0 -6
  21. inferno/__main__.py +0 -9
  22. inferno/cli.py +0 -6
  23. webscout/Extra/GitToolkit/__init__.py +0 -10
  24. webscout/Extra/GitToolkit/gitapi/__init__.py +0 -12
  25. webscout/Extra/GitToolkit/gitapi/repository.py +0 -195
  26. webscout/Extra/GitToolkit/gitapi/user.py +0 -96
  27. webscout/Extra/GitToolkit/gitapi/utils.py +0 -62
  28. webscout/Extra/YTToolkit/YTdownloader.py +0 -957
  29. webscout/Extra/YTToolkit/__init__.py +0 -3
  30. webscout/Extra/YTToolkit/transcriber.py +0 -476
  31. webscout/Extra/YTToolkit/ytapi/__init__.py +0 -6
  32. webscout/Extra/YTToolkit/ytapi/channel.py +0 -307
  33. webscout/Extra/YTToolkit/ytapi/errors.py +0 -13
  34. webscout/Extra/YTToolkit/ytapi/extras.py +0 -45
  35. webscout/Extra/YTToolkit/ytapi/https.py +0 -88
  36. webscout/Extra/YTToolkit/ytapi/patterns.py +0 -61
  37. webscout/Extra/YTToolkit/ytapi/playlist.py +0 -59
  38. webscout/Extra/YTToolkit/ytapi/pool.py +0 -8
  39. webscout/Extra/YTToolkit/ytapi/query.py +0 -40
  40. webscout/Extra/YTToolkit/ytapi/stream.py +0 -63
  41. webscout/Extra/YTToolkit/ytapi/utils.py +0 -62
  42. webscout/Extra/YTToolkit/ytapi/video.py +0 -232
  43. webscout/Extra/__init__.py +0 -7
  44. webscout/Extra/autocoder/__init__.py +0 -9
  45. webscout/Extra/autocoder/autocoder.py +0 -849
  46. webscout/Extra/autocoder/autocoder_utiles.py +0 -332
  47. webscout/Extra/gguf.py +0 -682
  48. webscout/Extra/tempmail/__init__.py +0 -28
  49. webscout/Extra/tempmail/async_utils.py +0 -141
  50. webscout/Extra/tempmail/base.py +0 -161
  51. webscout/Extra/tempmail/cli.py +0 -187
  52. webscout/Extra/tempmail/emailnator.py +0 -84
  53. webscout/Extra/tempmail/mail_tm.py +0 -361
  54. webscout/Extra/tempmail/temp_mail_io.py +0 -292
  55. webscout/Extra/weather.py +0 -194
  56. webscout/Extra/weather_ascii.py +0 -76
  57. webscout/LLM.py +0 -442
  58. webscout/Litlogger/__init__.py +0 -67
  59. webscout/Litlogger/core/__init__.py +0 -6
  60. webscout/Litlogger/core/level.py +0 -23
  61. webscout/Litlogger/core/logger.py +0 -165
  62. webscout/Litlogger/handlers/__init__.py +0 -12
  63. webscout/Litlogger/handlers/console.py +0 -33
  64. webscout/Litlogger/handlers/file.py +0 -143
  65. webscout/Litlogger/handlers/network.py +0 -173
  66. webscout/Litlogger/styles/__init__.py +0 -7
  67. webscout/Litlogger/styles/colors.py +0 -249
  68. webscout/Litlogger/styles/formats.py +0 -458
  69. webscout/Litlogger/styles/text.py +0 -87
  70. webscout/Litlogger/utils/__init__.py +0 -6
  71. webscout/Litlogger/utils/detectors.py +0 -153
  72. webscout/Litlogger/utils/formatters.py +0 -200
  73. webscout/Local/__init__.py +0 -12
  74. webscout/Local/__main__.py +0 -9
  75. webscout/Local/api.py +0 -576
  76. webscout/Local/cli.py +0 -516
  77. webscout/Local/config.py +0 -75
  78. webscout/Local/llm.py +0 -287
  79. webscout/Local/model_manager.py +0 -253
  80. webscout/Local/server.py +0 -721
  81. webscout/Local/utils.py +0 -93
  82. webscout/Provider/AI21.py +0 -177
  83. webscout/Provider/AISEARCH/DeepFind.py +0 -250
  84. webscout/Provider/AISEARCH/ISou.py +0 -256
  85. webscout/Provider/AISEARCH/Perplexity.py +0 -359
  86. webscout/Provider/AISEARCH/__init__.py +0 -10
  87. webscout/Provider/AISEARCH/felo_search.py +0 -228
  88. webscout/Provider/AISEARCH/genspark_search.py +0 -208
  89. webscout/Provider/AISEARCH/hika_search.py +0 -194
  90. webscout/Provider/AISEARCH/iask_search.py +0 -436
  91. webscout/Provider/AISEARCH/monica_search.py +0 -246
  92. webscout/Provider/AISEARCH/scira_search.py +0 -324
  93. webscout/Provider/AISEARCH/webpilotai_search.py +0 -281
  94. webscout/Provider/Aitopia.py +0 -292
  95. webscout/Provider/AllenAI.py +0 -413
  96. webscout/Provider/Andi.py +0 -228
  97. webscout/Provider/Blackboxai.py +0 -229
  98. webscout/Provider/C4ai.py +0 -432
  99. webscout/Provider/ChatGPTClone.py +0 -226
  100. webscout/Provider/ChatGPTES.py +0 -237
  101. webscout/Provider/ChatGPTGratis.py +0 -194
  102. webscout/Provider/Chatify.py +0 -175
  103. webscout/Provider/Cloudflare.py +0 -273
  104. webscout/Provider/Cohere.py +0 -208
  105. webscout/Provider/DeepSeek.py +0 -196
  106. webscout/Provider/Deepinfra.py +0 -297
  107. webscout/Provider/ElectronHub.py +0 -709
  108. webscout/Provider/ExaAI.py +0 -261
  109. webscout/Provider/ExaChat.py +0 -342
  110. webscout/Provider/Free2GPT.py +0 -241
  111. webscout/Provider/GPTWeb.py +0 -193
  112. webscout/Provider/Gemini.py +0 -169
  113. webscout/Provider/GithubChat.py +0 -367
  114. webscout/Provider/Glider.py +0 -211
  115. webscout/Provider/Groq.py +0 -670
  116. webscout/Provider/HF_space/__init__.py +0 -0
  117. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  118. webscout/Provider/HeckAI.py +0 -233
  119. webscout/Provider/HuggingFaceChat.py +0 -462
  120. webscout/Provider/Hunyuan.py +0 -272
  121. webscout/Provider/Jadve.py +0 -266
  122. webscout/Provider/Koboldai.py +0 -381
  123. webscout/Provider/LambdaChat.py +0 -392
  124. webscout/Provider/Llama.py +0 -200
  125. webscout/Provider/Llama3.py +0 -204
  126. webscout/Provider/Marcus.py +0 -148
  127. webscout/Provider/Netwrck.py +0 -228
  128. webscout/Provider/OLLAMA.py +0 -396
  129. webscout/Provider/OPENAI/__init__.py +0 -25
  130. webscout/Provider/OPENAI/base.py +0 -46
  131. webscout/Provider/OPENAI/c4ai.py +0 -367
  132. webscout/Provider/OPENAI/chatgpt.py +0 -549
  133. webscout/Provider/OPENAI/chatgptclone.py +0 -460
  134. webscout/Provider/OPENAI/deepinfra.py +0 -272
  135. webscout/Provider/OPENAI/e2b.py +0 -1350
  136. webscout/Provider/OPENAI/exaai.py +0 -404
  137. webscout/Provider/OPENAI/exachat.py +0 -433
  138. webscout/Provider/OPENAI/freeaichat.py +0 -352
  139. webscout/Provider/OPENAI/glider.py +0 -316
  140. webscout/Provider/OPENAI/heckai.py +0 -337
  141. webscout/Provider/OPENAI/llmchatco.py +0 -327
  142. webscout/Provider/OPENAI/netwrck.py +0 -348
  143. webscout/Provider/OPENAI/opkfc.py +0 -488
  144. webscout/Provider/OPENAI/scirachat.py +0 -463
  145. webscout/Provider/OPENAI/sonus.py +0 -294
  146. webscout/Provider/OPENAI/standardinput.py +0 -425
  147. webscout/Provider/OPENAI/textpollinations.py +0 -285
  148. webscout/Provider/OPENAI/toolbaz.py +0 -405
  149. webscout/Provider/OPENAI/typegpt.py +0 -346
  150. webscout/Provider/OPENAI/uncovrAI.py +0 -455
  151. webscout/Provider/OPENAI/utils.py +0 -211
  152. webscout/Provider/OPENAI/venice.py +0 -413
  153. webscout/Provider/OPENAI/wisecat.py +0 -381
  154. webscout/Provider/OPENAI/writecream.py +0 -156
  155. webscout/Provider/OPENAI/x0gpt.py +0 -371
  156. webscout/Provider/OPENAI/yep.py +0 -327
  157. webscout/Provider/OpenGPT.py +0 -199
  158. webscout/Provider/Openai.py +0 -496
  159. webscout/Provider/PI.py +0 -344
  160. webscout/Provider/Perplexitylabs.py +0 -415
  161. webscout/Provider/Phind.py +0 -535
  162. webscout/Provider/PizzaGPT.py +0 -198
  163. webscout/Provider/QwenLM.py +0 -254
  164. webscout/Provider/Reka.py +0 -214
  165. webscout/Provider/StandardInput.py +0 -278
  166. webscout/Provider/TTI/AiForce/__init__.py +0 -22
  167. webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
  168. webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
  169. webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
  170. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
  171. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
  172. webscout/Provider/TTI/ImgSys/__init__.py +0 -23
  173. webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
  174. webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
  175. webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
  176. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
  177. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
  178. webscout/Provider/TTI/Nexra/__init__.py +0 -22
  179. webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
  180. webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
  181. webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
  182. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
  183. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
  184. webscout/Provider/TTI/__init__.py +0 -12
  185. webscout/Provider/TTI/aiarta/__init__.py +0 -2
  186. webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
  187. webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
  188. webscout/Provider/TTI/artbit/__init__.py +0 -22
  189. webscout/Provider/TTI/artbit/async_artbit.py +0 -155
  190. webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
  191. webscout/Provider/TTI/fastflux/__init__.py +0 -22
  192. webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
  193. webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
  194. webscout/Provider/TTI/huggingface/__init__.py +0 -22
  195. webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
  196. webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
  197. webscout/Provider/TTI/piclumen/__init__.py +0 -23
  198. webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
  199. webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
  200. webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
  201. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
  202. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
  203. webscout/Provider/TTI/talkai/__init__.py +0 -4
  204. webscout/Provider/TTI/talkai/async_talkai.py +0 -229
  205. webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
  206. webscout/Provider/TTS/__init__.py +0 -7
  207. webscout/Provider/TTS/deepgram.py +0 -156
  208. webscout/Provider/TTS/elevenlabs.py +0 -111
  209. webscout/Provider/TTS/gesserit.py +0 -127
  210. webscout/Provider/TTS/murfai.py +0 -113
  211. webscout/Provider/TTS/parler.py +0 -111
  212. webscout/Provider/TTS/speechma.py +0 -180
  213. webscout/Provider/TTS/streamElements.py +0 -333
  214. webscout/Provider/TTS/utils.py +0 -280
  215. webscout/Provider/TeachAnything.py +0 -187
  216. webscout/Provider/TextPollinationsAI.py +0 -231
  217. webscout/Provider/TwoAI.py +0 -199
  218. webscout/Provider/Venice.py +0 -219
  219. webscout/Provider/VercelAI.py +0 -234
  220. webscout/Provider/WebSim.py +0 -228
  221. webscout/Provider/WiseCat.py +0 -196
  222. webscout/Provider/Writecream.py +0 -211
  223. webscout/Provider/WritingMate.py +0 -197
  224. webscout/Provider/Youchat.py +0 -330
  225. webscout/Provider/__init__.py +0 -198
  226. webscout/Provider/ai4chat.py +0 -202
  227. webscout/Provider/aimathgpt.py +0 -189
  228. webscout/Provider/akashgpt.py +0 -342
  229. webscout/Provider/askmyai.py +0 -158
  230. webscout/Provider/asksteve.py +0 -203
  231. webscout/Provider/bagoodex.py +0 -145
  232. webscout/Provider/cerebras.py +0 -242
  233. webscout/Provider/chatglm.py +0 -205
  234. webscout/Provider/cleeai.py +0 -213
  235. webscout/Provider/copilot.py +0 -428
  236. webscout/Provider/elmo.py +0 -234
  237. webscout/Provider/freeaichat.py +0 -271
  238. webscout/Provider/gaurish.py +0 -244
  239. webscout/Provider/geminiapi.py +0 -208
  240. webscout/Provider/geminiprorealtime.py +0 -160
  241. webscout/Provider/granite.py +0 -187
  242. webscout/Provider/hermes.py +0 -219
  243. webscout/Provider/julius.py +0 -223
  244. webscout/Provider/koala.py +0 -268
  245. webscout/Provider/labyrinth.py +0 -340
  246. webscout/Provider/learnfastai.py +0 -266
  247. webscout/Provider/lepton.py +0 -194
  248. webscout/Provider/llama3mitril.py +0 -180
  249. webscout/Provider/llamatutor.py +0 -192
  250. webscout/Provider/llmchat.py +0 -213
  251. webscout/Provider/llmchatco.py +0 -311
  252. webscout/Provider/meta.py +0 -794
  253. webscout/Provider/multichat.py +0 -325
  254. webscout/Provider/promptrefine.py +0 -193
  255. webscout/Provider/scira_chat.py +0 -277
  256. webscout/Provider/scnet.py +0 -187
  257. webscout/Provider/searchchat.py +0 -293
  258. webscout/Provider/sonus.py +0 -208
  259. webscout/Provider/talkai.py +0 -194
  260. webscout/Provider/toolbaz.py +0 -320
  261. webscout/Provider/turboseek.py +0 -219
  262. webscout/Provider/tutorai.py +0 -252
  263. webscout/Provider/typefully.py +0 -280
  264. webscout/Provider/typegpt.py +0 -232
  265. webscout/Provider/uncovr.py +0 -312
  266. webscout/Provider/x0gpt.py +0 -256
  267. webscout/Provider/yep.py +0 -376
  268. webscout/litagent/__init__.py +0 -29
  269. webscout/litagent/agent.py +0 -455
  270. webscout/litagent/constants.py +0 -60
  271. webscout/litprinter/__init__.py +0 -59
  272. webscout/scout/__init__.py +0 -8
  273. webscout/scout/core/__init__.py +0 -7
  274. webscout/scout/core/crawler.py +0 -140
  275. webscout/scout/core/scout.py +0 -568
  276. webscout/scout/core/search_result.py +0 -96
  277. webscout/scout/core/text_analyzer.py +0 -63
  278. webscout/scout/core/text_utils.py +0 -277
  279. webscout/scout/core/web_analyzer.py +0 -52
  280. webscout/scout/core.py +0 -881
  281. webscout/scout/element.py +0 -460
  282. webscout/scout/parsers/__init__.py +0 -69
  283. webscout/scout/parsers/html5lib_parser.py +0 -172
  284. webscout/scout/parsers/html_parser.py +0 -236
  285. webscout/scout/parsers/lxml_parser.py +0 -178
  286. webscout/scout/utils.py +0 -37
  287. webscout/swiftcli/__init__.py +0 -809
  288. webscout/zeroart/__init__.py +0 -55
  289. webscout/zeroart/base.py +0 -60
  290. webscout/zeroart/effects.py +0 -99
  291. webscout/zeroart/fonts.py +0 -816
  292. webscout-8.2.2.dist-info/RECORD +0 -309
  293. webscout-8.2.2.dist-info/entry_points.txt +0 -5
  294. webscout-8.2.2.dist-info/top_level.txt +0 -3
  295. webstoken/__init__.py +0 -30
  296. webstoken/classifier.py +0 -189
  297. webstoken/keywords.py +0 -216
  298. webstoken/language.py +0 -128
  299. webstoken/ner.py +0 -164
  300. webstoken/normalizer.py +0 -35
  301. webstoken/processor.py +0 -77
  302. webstoken/sentiment.py +0 -206
  303. webstoken/stemmer.py +0 -73
  304. webstoken/tagger.py +0 -60
  305. webstoken/tokenizer.py +0 -158
  306. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info/licenses}/LICENSE.md +0 -0
@@ -1,87 +0,0 @@
1
- import textwrap
2
- from typing import Optional
3
-
4
- class TextStyle:
5
- @staticmethod
6
- def wrap(text: str, width: int = 80, indent: str = "") -> str:
7
- """Wrap text to specified width with optional indentation."""
8
- return textwrap.fill(text, width=width, initial_indent=indent,
9
- subsequent_indent=indent)
10
-
11
- @staticmethod
12
- def truncate(text: str, max_length: int, suffix: str = "...") -> str:
13
- """Truncate text to maximum length with suffix."""
14
- if len(text) <= max_length:
15
- return text
16
- return text[:max_length - len(suffix)] + suffix
17
-
18
- @staticmethod
19
- def pad(text: str, width: int, align: str = "left",
20
- fill_char: str = " ") -> str:
21
- """Pad text to specified width with alignment."""
22
- if align == "left":
23
- return text.ljust(width, fill_char)
24
- elif align == "right":
25
- return text.rjust(width, fill_char)
26
- elif align == "center":
27
- return text.center(width, fill_char)
28
- raise ValueError(f"Invalid alignment: {align}")
29
-
30
- @staticmethod
31
- def indent(text: str, prefix: str = " ", predicate: Optional[callable] = None) -> str:
32
- """Indent text lines with prefix based on optional predicate."""
33
- lines = text.splitlines(True)
34
- if predicate is None:
35
- predicate = bool
36
-
37
- def should_indent(line):
38
- return predicate(line)
39
-
40
- return "".join(prefix + line if should_indent(line) else line
41
- for line in lines)
42
-
43
- @staticmethod
44
- def highlight(text: str, substring: str, color: str) -> str:
45
- """Highlight substring within text using ANSI color codes."""
46
- from ..styles.colors import LogColors
47
- if not substring:
48
- return text
49
-
50
- parts = text.split(substring)
51
- highlighted = f"{color}{substring}{LogColors.RESET}"
52
- return highlighted.join(parts)
53
-
54
- @staticmethod
55
- def table(headers: list, rows: list, padding: int = 1) -> str:
56
- """Create a formatted table with headers and rows."""
57
- if not rows:
58
- return ""
59
-
60
- # Calculate column widths
61
- widths = [max(len(str(row[i])) for row in [headers] + rows)
62
- for i in range(len(headers))]
63
-
64
- # Create separator line
65
- separator = "+" + "+".join("-" * (w + 2 * padding) for w in widths) + "+"
66
-
67
- # Format header
68
- header = "|" + "|".join(
69
- str(h).center(w + 2 * padding) for h, w in zip(headers, widths)
70
- ) + "|"
71
-
72
- # Format rows
73
- formatted_rows = []
74
- for row in rows:
75
- formatted_row = "|" + "|".join(
76
- str(cell).ljust(w + 2 * padding) for cell, w in zip(row, widths)
77
- ) + "|"
78
- formatted_rows.append(formatted_row)
79
-
80
- # Combine all parts
81
- return "\n".join([
82
- separator,
83
- header,
84
- separator,
85
- *formatted_rows,
86
- separator
87
- ])
@@ -1,6 +0,0 @@
1
- """Utility functions for log level detection and message formatting."""
2
-
3
- from .detectors import LevelDetector
4
- from .formatters import MessageFormatter
5
-
6
- __all__ = ["LevelDetector", "MessageFormatter"]
@@ -1,153 +0,0 @@
1
- import re
2
- import sys
3
- from typing import Optional
4
- from ..core.level import LogLevel
5
-
6
- class LevelDetector:
7
- """Utility class for intelligent log level detection."""
8
-
9
- # Common patterns indicating error conditions
10
- ERROR_PATTERNS = [
11
- r"error",
12
- r"exception",
13
- r"failed",
14
- r"failure",
15
- r"traceback",
16
- r"crash",
17
- r"fatal",
18
- ]
19
-
20
- # Common patterns indicating warning conditions
21
- WARNING_PATTERNS = [
22
- r"warning",
23
- r"warn",
24
- r"deprecated",
25
- r"might",
26
- r"consider",
27
- r"attention",
28
- ]
29
-
30
- # Common patterns indicating debug information
31
- DEBUG_PATTERNS = [
32
- r"debug",
33
- r"trace",
34
- r"verbose",
35
- r"detail",
36
- ]
37
-
38
- @classmethod
39
- def detect_level(cls, message: str, exception: Optional[Exception] = None) -> LogLevel:
40
- """
41
- Detect appropriate log level from message content and context.
42
-
43
- Args:
44
- message: Log message to analyze
45
- exception: Optional exception object
46
-
47
- Returns:
48
- Detected LogLevel
49
- """
50
- # If there's an exception, it's at least ERROR
51
- if exception is not None:
52
- if isinstance(exception, (SystemExit, KeyboardInterrupt)):
53
- return LogLevel.CRITICAL
54
- return LogLevel.ERROR
55
-
56
- # Convert to lowercase for pattern matching
57
- message_lower = message.lower()
58
-
59
- # Check for error patterns
60
- for pattern in cls.ERROR_PATTERNS:
61
- if re.search(pattern, message_lower):
62
- return LogLevel.ERROR
63
-
64
- # Check for warning patterns
65
- for pattern in cls.WARNING_PATTERNS:
66
- if re.search(pattern, message_lower):
67
- return LogLevel.WARNING
68
-
69
- # Check for debug patterns
70
- for pattern in cls.DEBUG_PATTERNS:
71
- if re.search(pattern, message_lower):
72
- return LogLevel.DEBUG
73
-
74
- # Default to INFO
75
- return LogLevel.INFO
76
-
77
- @classmethod
78
- def detect_level_from_exception(cls, exc_type, exc_value, exc_tb) -> LogLevel:
79
- """
80
- Detect log level from exception information.
81
-
82
- Args:
83
- exc_type: Exception type
84
- exc_value: Exception value
85
- exc_tb: Exception traceback
86
-
87
- Returns:
88
- Detected LogLevel
89
- """
90
- # Critical errors that should terminate execution
91
- if exc_type in (SystemExit, KeyboardInterrupt, MemoryError):
92
- return LogLevel.CRITICAL
93
-
94
- # Built-in exceptions that indicate programming errors
95
- if exc_type in (
96
- SyntaxError,
97
- IndentationError,
98
- NameError,
99
- TypeError,
100
- AttributeError
101
- ):
102
- return LogLevel.ERROR
103
-
104
- # Runtime errors that might be recoverable
105
- if exc_type in (
106
- ValueError,
107
- KeyError,
108
- IOError,
109
- OSError,
110
- ConnectionError
111
- ):
112
- return LogLevel.WARNING
113
-
114
- # Default to ERROR for unknown exception types
115
- return LogLevel.ERROR
116
-
117
- @classmethod
118
- def detect_level_from_frame(cls, frame_depth: int = 1) -> LogLevel:
119
- """
120
- Detect log level by analyzing the call stack.
121
-
122
- Args:
123
- frame_depth: How many frames up to look (1 = caller's frame)
124
-
125
- Returns:
126
- Detected LogLevel
127
- """
128
- try:
129
- frame = sys._getframe(frame_depth)
130
-
131
- # Check function/method name
132
- code = frame.f_code
133
- func_name = code.co_name.lower()
134
-
135
- if any(p in func_name for p in ["error", "fail", "crash"]):
136
- return LogLevel.ERROR
137
- if any(p in func_name for p in ["warn"]):
138
- return LogLevel.WARNING
139
- if any(p in func_name for p in ["debug", "trace"]):
140
- return LogLevel.DEBUG
141
-
142
- # Check local variables for exceptions
143
- locals_dict = frame.f_locals
144
- for value in locals_dict.values():
145
- if isinstance(value, Exception):
146
- return cls.detect_level_from_exception(
147
- type(value), value, value.__traceback__
148
- )
149
-
150
- return LogLevel.INFO
151
-
152
- except Exception:
153
- return LogLevel.INFO # Default if detection fails
@@ -1,200 +0,0 @@
1
- import json
2
- import re
3
- import traceback
4
- from datetime import datetime
5
- from typing import Any, Dict, Optional, Union
6
-
7
- class MessageFormatter:
8
- """Utility class for formatting log messages."""
9
-
10
- @staticmethod
11
- def format_exception(exc_info: tuple) -> str:
12
- """
13
- Format exception information into a readable string.
14
-
15
- Args:
16
- exc_info: Tuple of (type, value, traceback)
17
-
18
- Returns:
19
- Formatted exception string
20
- """
21
- return "".join(traceback.format_exception(*exc_info))
22
-
23
- @staticmethod
24
- def format_dict(data: Dict[str, Any], indent: int = 2) -> str:
25
- """
26
- Format dictionary into pretty-printed string.
27
-
28
- Args:
29
- data: Dictionary to format
30
- indent: Number of spaces for indentation
31
-
32
- Returns:
33
- Formatted string representation
34
- """
35
- return json.dumps(data, indent=indent, default=str, ensure_ascii=False)
36
-
37
- @staticmethod
38
- def format_object(obj: Any) -> str:
39
- """
40
- Format any object into a string representation.
41
-
42
- Args:
43
- obj: Object to format
44
-
45
- Returns:
46
- String representation of object
47
- """
48
- if hasattr(obj, "to_dict"):
49
- return MessageFormatter.format_dict(obj.to_dict())
50
- if hasattr(obj, "__dict__"):
51
- return MessageFormatter.format_dict(obj.__dict__)
52
- return str(obj)
53
-
54
- @staticmethod
55
- def truncate(message: str, max_length: int = 1000, suffix: str = "...") -> str:
56
- """
57
- Truncate message to maximum length.
58
-
59
- Args:
60
- message: Message to truncate
61
- max_length: Maximum length
62
- suffix: String to append when truncated
63
-
64
- Returns:
65
- Truncated message
66
- """
67
- if len(message) <= max_length:
68
- return message
69
- return message[:max_length - len(suffix)] + suffix
70
-
71
- @staticmethod
72
- def mask_sensitive(message: str, patterns: Dict[str, str]) -> str:
73
- """
74
- Mask sensitive information in message.
75
-
76
- Args:
77
- message: Message to process
78
- patterns: Dictionary of {pattern: mask}
79
-
80
- Returns:
81
- Message with sensitive info masked
82
- """
83
- result = message
84
- for pattern, mask in patterns.items():
85
- result = re.sub(pattern, mask, result)
86
- return result
87
-
88
- @staticmethod
89
- def format_context(context: Dict[str, Any]) -> str:
90
- """
91
- Format context dictionary into readable string.
92
-
93
- Args:
94
- context: Context dictionary
95
-
96
- Returns:
97
- Formatted context string
98
- """
99
- parts = []
100
- for key, value in sorted(context.items()):
101
- formatted_value = (
102
- MessageFormatter.format_object(value)
103
- if isinstance(value, (dict, list, tuple))
104
- else str(value)
105
- )
106
- parts.append(f"{key}={formatted_value}")
107
- return " ".join(parts)
108
-
109
- @staticmethod
110
- def format_metrics(metrics: Dict[str, Union[int, float]]) -> str:
111
- """
112
- Format performance metrics into readable string.
113
-
114
- Args:
115
- metrics: Dictionary of metric names and values
116
-
117
- Returns:
118
- Formatted metrics string
119
- """
120
- parts = []
121
- for key, value in sorted(metrics.items()):
122
- if isinstance(value, float):
123
- formatted = f"{value:.3f}"
124
- else:
125
- formatted = str(value)
126
- parts.append(f"{key}={formatted}")
127
- return " ".join(parts)
128
-
129
- @staticmethod
130
- def format_timestamp(
131
- timestamp: Optional[datetime] = None,
132
- format: str = "%Y-%m-%d %H:%M:%S.%f"
133
- ) -> str:
134
- """
135
- Format timestamp into string.
136
-
137
- Args:
138
- timestamp: Datetime object (uses current time if None)
139
- format: strftime format string
140
-
141
- Returns:
142
- Formatted timestamp string
143
- """
144
- if timestamp is None:
145
- timestamp = datetime.now()
146
- return timestamp.strftime(format)
147
-
148
- @classmethod
149
- def format_message(
150
- cls,
151
- message: str,
152
- context: Optional[Dict[str, Any]] = None,
153
- metrics: Optional[Dict[str, Union[int, float]]] = None,
154
- max_length: Optional[int] = None,
155
- mask_patterns: Optional[Dict[str, str]] = None,
156
- timestamp_format: Optional[str] = None
157
- ) -> str:
158
- """
159
- Format complete log message with all options.
160
-
161
- Args:
162
- message: Base message
163
- context: Optional context dictionary
164
- metrics: Optional performance metrics
165
- max_length: Optional maximum length
166
- mask_patterns: Optional sensitive data patterns
167
- timestamp_format: Optional timestamp format
168
-
169
- Returns:
170
- Formatted complete message
171
- """
172
- parts = []
173
-
174
- # Add timestamp
175
- if timestamp_format:
176
- parts.append(cls.format_timestamp(format=timestamp_format))
177
-
178
- # Add main message
179
- parts.append(message)
180
-
181
- # Add context if present
182
- if context:
183
- parts.append(cls.format_context(context))
184
-
185
- # Add metrics if present
186
- if metrics:
187
- parts.append(cls.format_metrics(metrics))
188
-
189
- # Join all parts
190
- result = " ".join(parts)
191
-
192
- # Apply masking if needed
193
- if mask_patterns:
194
- result = cls.mask_sensitive(result, mask_patterns)
195
-
196
- # Apply length limit if needed
197
- if max_length:
198
- result = cls.truncate(result, max_length)
199
-
200
- return result
@@ -1,12 +0,0 @@
1
- """
2
- Webscout.Local - A llama-cpp-python based LLM serving tool with Ollama-compatible API
3
- """
4
- from webscout.version import __version__
5
-
6
- # Import main components for easier access
7
- from .llm import LLMInterface
8
- from .model_manager import ModelManager
9
- from .server import start_server
10
-
11
- # Define what's available when using `from webscout.Local import *`
12
- __all__ = ["LLMInterface", "ModelManager", "start_server"]
@@ -1,9 +0,0 @@
1
- """
2
- Entry point for running webscout.Local as a module.
3
- This allows running the CLI using 'python -m webscout.Local'.
4
- """
5
-
6
- from webscout.Local.cli import app
7
-
8
- if __name__ == "__main__":
9
- app()