webscout 8.2.5__py3-none-any.whl → 8.2.6__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 (45) hide show
  1. webscout/AIauto.py +112 -22
  2. webscout/AIutel.py +240 -344
  3. webscout/Extra/autocoder/autocoder.py +66 -5
  4. webscout/Provider/AISEARCH/scira_search.py +2 -1
  5. webscout/Provider/GizAI.py +6 -4
  6. webscout/Provider/Nemotron.py +218 -0
  7. webscout/Provider/OPENAI/scirachat.py +2 -1
  8. webscout/Provider/TeachAnything.py +8 -5
  9. webscout/Provider/WiseCat.py +1 -1
  10. webscout/Provider/WrDoChat.py +370 -0
  11. webscout/Provider/__init__.py +4 -6
  12. webscout/Provider/ai4chat.py +5 -3
  13. webscout/Provider/akashgpt.py +59 -66
  14. webscout/Provider/freeaichat.py +57 -43
  15. webscout/Provider/scira_chat.py +2 -1
  16. webscout/Provider/scnet.py +4 -1
  17. webscout/__init__.py +0 -1
  18. webscout/conversation.py +305 -446
  19. webscout/swiftcli/__init__.py +80 -794
  20. webscout/swiftcli/core/__init__.py +7 -0
  21. webscout/swiftcli/core/cli.py +297 -0
  22. webscout/swiftcli/core/context.py +104 -0
  23. webscout/swiftcli/core/group.py +241 -0
  24. webscout/swiftcli/decorators/__init__.py +28 -0
  25. webscout/swiftcli/decorators/command.py +221 -0
  26. webscout/swiftcli/decorators/options.py +220 -0
  27. webscout/swiftcli/decorators/output.py +252 -0
  28. webscout/swiftcli/exceptions.py +21 -0
  29. webscout/swiftcli/plugins/__init__.py +9 -0
  30. webscout/swiftcli/plugins/base.py +135 -0
  31. webscout/swiftcli/plugins/manager.py +262 -0
  32. webscout/swiftcli/utils/__init__.py +59 -0
  33. webscout/swiftcli/utils/formatting.py +252 -0
  34. webscout/swiftcli/utils/parsing.py +267 -0
  35. webscout/version.py +1 -1
  36. {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/METADATA +1 -1
  37. {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/RECORD +41 -28
  38. webscout/LLM.py +0 -442
  39. webscout/Provider/PizzaGPT.py +0 -228
  40. webscout/Provider/promptrefine.py +0 -193
  41. webscout/Provider/tutorai.py +0 -270
  42. {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/WHEEL +0 -0
  43. {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/entry_points.txt +0 -0
  44. {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/licenses/LICENSE.md +0 -0
  45. {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,7 @@
1
+ """Core functionality for SwiftCLI."""
2
+
3
+ from .cli import CLI
4
+ from .context import Context
5
+ from .group import Group
6
+
7
+ __all__ = ['CLI', 'Context', 'Group']
@@ -0,0 +1,297 @@
1
+ """Main CLI application class."""
2
+
3
+ import sys
4
+ from typing import Any, Dict, List, Optional, Union
5
+
6
+ from rich.console import Console
7
+
8
+ from ..exceptions import UsageError
9
+ from ..plugins.manager import PluginManager
10
+ from ..utils.formatting import format_error, format_success
11
+ from .context import Context
12
+
13
+ console = Console()
14
+
15
+ class CLI:
16
+ """
17
+ Main CLI application class.
18
+
19
+ The CLI class is the core of SwiftCLI. It handles command registration,
20
+ argument parsing, and command execution. It also manages plugins and
21
+ provides the main entry point for CLI applications.
22
+
23
+ Attributes:
24
+ name: Application name
25
+ help: Application description
26
+ version: Application version
27
+ debug: Debug mode flag
28
+ commands: Registered commands
29
+ groups: Command groups
30
+ plugin_manager: Plugin manager instance
31
+
32
+ Example:
33
+ >>> app = CLI(name="myapp", version="1.0.0")
34
+ >>> @app.command()
35
+ ... def greet(name: str):
36
+ ... '''Greet someone'''
37
+ ... print(f"Hello {name}!")
38
+ >>> app.run()
39
+ """
40
+
41
+ def __init__(
42
+ self,
43
+ name: str,
44
+ help: Optional[str] = None,
45
+ version: Optional[str] = None,
46
+ debug: bool = False
47
+ ):
48
+ """
49
+ Initialize CLI application.
50
+
51
+ Args:
52
+ name: Application name
53
+ help: Application description
54
+ version: Application version
55
+ debug: Enable debug mode
56
+ """
57
+ self.name = name
58
+ self.help = help
59
+ self.version = version
60
+ self.debug = debug
61
+
62
+ self.commands: Dict[str, Dict[str, Any]] = {}
63
+ self.groups: Dict[str, 'Group'] = {} # type: ignore
64
+ self.plugin_manager = PluginManager()
65
+
66
+ # Initialize plugin manager with this CLI instance
67
+ self.plugin_manager.init_plugins(self)
68
+
69
+ def command(
70
+ self,
71
+ name: Optional[str] = None,
72
+ help: Optional[str] = None,
73
+ aliases: Optional[List[str]] = None,
74
+ hidden: bool = False
75
+ ):
76
+ """
77
+ Decorator to register a command.
78
+
79
+ Args:
80
+ name: Command name (defaults to function name)
81
+ help: Command help text
82
+ aliases: Alternative command names
83
+ hidden: Hide from help output
84
+
85
+ Example:
86
+ @app.command()
87
+ def hello(name: str):
88
+ '''Say hello'''
89
+ print(f"Hello {name}!")
90
+ """
91
+ def decorator(f):
92
+ cmd_name = name or f.__name__
93
+ self.commands[cmd_name] = {
94
+ 'func': f,
95
+ 'help': help or f.__doc__,
96
+ 'aliases': aliases or [],
97
+ 'hidden': hidden
98
+ }
99
+
100
+ # Register aliases
101
+ for alias in (aliases or []):
102
+ self.commands[alias] = self.commands[cmd_name]
103
+
104
+ return f
105
+ return decorator
106
+
107
+ def group(
108
+ self,
109
+ name: Optional[str] = None,
110
+ help: Optional[str] = None,
111
+ **kwargs
112
+ ):
113
+ """
114
+ Create a command group.
115
+
116
+ Args:
117
+ name: Group name
118
+ help: Group help text
119
+ **kwargs: Additional group options
120
+
121
+ Example:
122
+ @app.group()
123
+ def db():
124
+ '''Database commands'''
125
+ pass
126
+
127
+ @db.command()
128
+ def migrate():
129
+ '''Run migrations'''
130
+ pass
131
+ """
132
+ from .group import Group # Import here to avoid circular dependency
133
+
134
+ def decorator(f):
135
+ group_name = name or f.__name__
136
+ group = Group(
137
+ name=group_name,
138
+ help=help or f.__doc__,
139
+ parent=self,
140
+ **kwargs
141
+ )
142
+ self.groups[group_name] = group
143
+ return group
144
+ return decorator
145
+
146
+ def run(self, args: Optional[List[str]] = None) -> int:
147
+ """
148
+ Run the CLI application.
149
+
150
+ Args:
151
+ args: Command line arguments (defaults to sys.argv[1:])
152
+
153
+ Returns:
154
+ Exit code (0 for success, non-zero for error)
155
+ """
156
+ try:
157
+ args = args or sys.argv[1:]
158
+
159
+ # Show help if no arguments
160
+ if not args or args[0] in ['-h', '--help']:
161
+ self._print_help()
162
+ return 0
163
+
164
+ # Show version if requested
165
+ if args[0] in ['-v', '--version'] and self.version:
166
+ console.print(self.version)
167
+ return 0
168
+
169
+ command_name = args[0]
170
+ command_args = args[1:]
171
+
172
+ # Check if it's a group command
173
+ if command_name in self.groups:
174
+ return self.groups[command_name].run(command_args)
175
+
176
+ # Check if it's a regular command
177
+ if command_name not in self.commands:
178
+ format_error(f"Unknown command: {command_name}")
179
+ self._print_help()
180
+ return 1
181
+
182
+ # Create command context
183
+ ctx = Context(self, command=command_name, debug=self.debug)
184
+
185
+ # Run command through plugin system
186
+ if not self.plugin_manager.before_command(command_name, command_args):
187
+ return 1
188
+
189
+ try:
190
+ command = self.commands[command_name]
191
+ result = command['func'](**self._parse_args(command, command_args))
192
+ self.plugin_manager.after_command(command_name, command_args, result)
193
+ return 0
194
+ except Exception as e:
195
+ self.plugin_manager.on_error(command_name, e)
196
+ if self.debug:
197
+ raise
198
+ format_error(str(e))
199
+ return 1
200
+
201
+ except KeyboardInterrupt:
202
+ console.print("\nOperation cancelled by user")
203
+ return 130
204
+ except Exception as e:
205
+ if self.debug:
206
+ raise
207
+ format_error(str(e))
208
+ return 1
209
+
210
+ def _parse_args(self, command: Dict[str, Any], args: List[str]) -> Dict[str, Any]:
211
+ """Parse command arguments."""
212
+ from ..utils.parsing import (
213
+ parse_args, validate_required, convert_type,
214
+ validate_choice, get_env_var
215
+ )
216
+
217
+ params = {}
218
+ func = command['func']
219
+
220
+ # Parse command-line arguments
221
+ parsed_args = parse_args(args)
222
+
223
+ # Handle options
224
+ if hasattr(func, '_options'):
225
+ for opt in func._options:
226
+ name = opt['param_decls'][0].lstrip('-').replace('-', '_')
227
+ if name in parsed_args:
228
+ value = parsed_args[name]
229
+ if 'type' in opt:
230
+ value = convert_type(value, opt['type'], name)
231
+ if 'choices' in opt and opt['choices']:
232
+ validate_choice(
233
+ value,
234
+ opt['choices'],
235
+ name,
236
+ opt.get('case_sensitive', True)
237
+ )
238
+ params[name] = value
239
+ elif opt.get('required', False):
240
+ raise UsageError(f"Missing required option: {name}")
241
+ elif 'default' in opt:
242
+ params[name] = opt['default']
243
+
244
+ # Handle arguments
245
+ if hasattr(func, '_arguments'):
246
+ for i, arg in enumerate(func._arguments):
247
+ name = arg['name']
248
+ if f'arg{i}' in parsed_args:
249
+ value = parsed_args[f'arg{i}']
250
+ if 'type' in arg:
251
+ value = convert_type(value, arg['type'], name)
252
+ params[name] = value
253
+ elif arg.get('required', True):
254
+ raise UsageError(f"Missing required argument: {name}")
255
+ elif 'default' in arg:
256
+ params[name] = arg['default']
257
+
258
+ # Handle environment variables
259
+ if hasattr(func, '_envvars'):
260
+ for env in func._envvars:
261
+ name = env['name'].lower()
262
+ value = get_env_var(
263
+ env['name'],
264
+ env.get('type', str),
265
+ env.get('required', False),
266
+ env.get('default')
267
+ )
268
+ if value is not None:
269
+ params[name] = value
270
+
271
+ return params
272
+
273
+ def _print_help(self) -> None:
274
+ """Print application help message."""
275
+ console.print(f"\n[bold]{self.name}[/]")
276
+ if self.help:
277
+ console.print(f"\n{self.help}")
278
+
279
+ # Show commands
280
+ console.print("\n[bold]Commands:[/]")
281
+ for name, cmd in self.commands.items():
282
+ if not cmd.get('hidden', False):
283
+ console.print(f" {name:20} {cmd['help'] or ''}")
284
+
285
+ # Show command groups
286
+ for name, group in self.groups.items():
287
+ console.print(f"\n[bold]{name} commands:[/]")
288
+ for cmd_name, cmd in group.commands.items():
289
+ if not cmd.get('hidden', False):
290
+ console.print(f" {cmd_name:20} {cmd['help'] or ''}")
291
+
292
+ console.print("\nUse -h or --help with any command for more info")
293
+ if self.version:
294
+ console.print("Use -v or --version to show version")
295
+
296
+ def __repr__(self) -> str:
297
+ return f"<CLI name={self.name}>"
@@ -0,0 +1,104 @@
1
+ """Context handling for SwiftCLI."""
2
+
3
+ from typing import Any, Dict, Optional
4
+
5
+ class Context:
6
+ """
7
+ Context object that holds state for the CLI app.
8
+
9
+ The Context class provides access to the CLI application instance and maintains
10
+ state throughout command execution. It can be used to pass data between
11
+ commands and access global configuration.
12
+
13
+ Attributes:
14
+ cli: The CLI application instance.
15
+ parent: The parent context if this is a subcommand.
16
+ command: The current command name.
17
+ obj: An object that can be used to store arbitrary data.
18
+ params: Dictionary of current command parameters.
19
+ debug: Debug mode flag.
20
+
21
+ Example:
22
+ @app.command()
23
+ @pass_context
24
+ def status(ctx):
25
+ '''Show application status'''
26
+ print(f"App: {ctx.cli.name}")
27
+ print(f"Debug: {ctx.debug}")
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ cli: 'CLI', # type: ignore
33
+ parent: Optional['Context'] = None,
34
+ command: Optional[str] = None,
35
+ obj: Any = None,
36
+ debug: bool = False
37
+ ):
38
+ self.cli = cli
39
+ self.parent = parent
40
+ self.command = command
41
+ self.obj = obj
42
+ self.params: Dict[str, Any] = {}
43
+ self.debug = debug
44
+
45
+ def get_parameter(self, name: str, default: Any = None) -> Any:
46
+ """
47
+ Get a parameter value from the context.
48
+
49
+ Args:
50
+ name: Parameter name
51
+ default: Default value if parameter not found
52
+
53
+ Returns:
54
+ Parameter value or default
55
+ """
56
+ return self.params.get(name, default)
57
+
58
+ def set_parameter(self, name: str, value: Any) -> None:
59
+ """
60
+ Set a parameter value in the context.
61
+
62
+ Args:
63
+ name: Parameter name
64
+ value: Parameter value
65
+ """
66
+ self.params[name] = value
67
+
68
+ def get_parent_context(self) -> Optional['Context']:
69
+ """Get the parent context if it exists."""
70
+ return self.parent
71
+
72
+ def create_child_context(
73
+ self,
74
+ command: Optional[str] = None,
75
+ obj: Any = None
76
+ ) -> 'Context':
77
+ """
78
+ Create a new child context.
79
+
80
+ Args:
81
+ command: Command name for the child context
82
+ obj: Object to store in child context
83
+
84
+ Returns:
85
+ New child context
86
+ """
87
+ return Context(
88
+ cli=self.cli,
89
+ parent=self,
90
+ command=command,
91
+ obj=obj,
92
+ debug=self.debug
93
+ )
94
+
95
+ @property
96
+ def root_context(self) -> 'Context':
97
+ """Get the root context by traversing up the parent chain."""
98
+ ctx = self
99
+ while ctx.parent is not None:
100
+ ctx = ctx.parent
101
+ return ctx
102
+
103
+ def __repr__(self) -> str:
104
+ return f"<Context command={self.command}>"
@@ -0,0 +1,241 @@
1
+ """Command group handling for SwiftCLI."""
2
+
3
+ from typing import Any, Dict, List, Optional, TYPE_CHECKING
4
+
5
+ from rich.console import Console
6
+
7
+ from ..exceptions import UsageError
8
+ from ..utils.formatting import format_error
9
+ from .context import Context
10
+
11
+ if TYPE_CHECKING:
12
+ from .cli import CLI
13
+
14
+ console = Console()
15
+
16
+ class Group:
17
+ """
18
+ Command group that can contain subcommands.
19
+
20
+ Groups allow organizing related commands together and support command
21
+ chaining for building command pipelines.
22
+
23
+ Attributes:
24
+ name: Group name
25
+ help: Group description
26
+ commands: Registered commands
27
+ parent: Parent CLI instance
28
+ chain: Enable command chaining
29
+ invoke_without_command: Allow invoking group without subcommand
30
+
31
+ Example:
32
+ @app.group()
33
+ def db():
34
+ '''Database commands'''
35
+ pass
36
+
37
+ @db.command()
38
+ def migrate():
39
+ '''Run database migrations'''
40
+ print("Running migrations...")
41
+ """
42
+
43
+ def __init__(
44
+ self,
45
+ name: str,
46
+ help: Optional[str] = None,
47
+ parent: Optional['CLI'] = None,
48
+ chain: bool = False,
49
+ invoke_without_command: bool = False
50
+ ):
51
+ """
52
+ Initialize command group.
53
+
54
+ Args:
55
+ name: Group name
56
+ help: Group description
57
+ parent: Parent CLI instance
58
+ chain: Enable command chaining
59
+ invoke_without_command: Allow invoking group without subcommand
60
+ """
61
+ self.name = name
62
+ self.help = help
63
+ self.parent = parent
64
+ self.chain = chain
65
+ self.invoke_without_command = invoke_without_command
66
+ self.commands: Dict[str, Dict[str, Any]] = {}
67
+
68
+ def command(
69
+ self,
70
+ name: Optional[str] = None,
71
+ help: Optional[str] = None,
72
+ aliases: Optional[List[str]] = None,
73
+ hidden: bool = False
74
+ ):
75
+ """
76
+ Decorator to register a command in this group.
77
+
78
+ Args:
79
+ name: Command name (defaults to function name)
80
+ help: Command help text
81
+ aliases: Alternative command names
82
+ hidden: Hide from help output
83
+
84
+ Example:
85
+ @group.command()
86
+ def status():
87
+ '''Show status'''
88
+ print("Status: OK")
89
+ """
90
+ def decorator(f):
91
+ cmd_name = name or f.__name__
92
+ self.commands[cmd_name] = {
93
+ 'func': f,
94
+ 'help': help or f.__doc__,
95
+ 'aliases': aliases or [],
96
+ 'hidden': hidden
97
+ }
98
+
99
+ # Register aliases
100
+ for alias in (aliases or []):
101
+ self.commands[alias] = self.commands[cmd_name]
102
+
103
+ return f
104
+ return decorator
105
+
106
+ def group(
107
+ self,
108
+ name: Optional[str] = None,
109
+ help: Optional[str] = None,
110
+ **kwargs
111
+ ):
112
+ """
113
+ Create a subgroup within this group.
114
+
115
+ Args:
116
+ name: Subgroup name
117
+ help: Subgroup help text
118
+ **kwargs: Additional group options
119
+
120
+ Example:
121
+ @group.group()
122
+ def config():
123
+ '''Configuration commands'''
124
+ pass
125
+ """
126
+ def decorator(f):
127
+ subgroup = Group(
128
+ name=name or f.__name__,
129
+ help=help or f.__doc__,
130
+ parent=self.parent,
131
+ **kwargs
132
+ )
133
+ self.commands[subgroup.name] = subgroup
134
+ return subgroup
135
+ return decorator
136
+
137
+ def run(self, args: List[str]) -> int:
138
+ """
139
+ Run a command in this group.
140
+
141
+ Args:
142
+ args: Command arguments
143
+
144
+ Returns:
145
+ Exit code (0 for success, non-zero for error)
146
+ """
147
+ try:
148
+ # Show help if no arguments or help requested
149
+ if not args or args[0] in ['-h', '--help']:
150
+ self._print_help()
151
+ return 0
152
+
153
+ command_name = args[0]
154
+ command_args = args[1:]
155
+
156
+ # Check if command exists
157
+ if command_name not in self.commands:
158
+ format_error(f"Unknown command: {self.name} {command_name}")
159
+ self._print_help()
160
+ return 1
161
+
162
+ command = self.commands[command_name]
163
+
164
+ # Handle nested groups
165
+ if isinstance(command, Group):
166
+ return command.run(command_args)
167
+
168
+ # Create command context
169
+ ctx = Context(
170
+ self.parent,
171
+ command=f"{self.name} {command_name}",
172
+ debug=getattr(self.parent, 'debug', False)
173
+ )
174
+
175
+ # Run command through plugin system
176
+ if self.parent and not self.parent.plugin_manager.before_command(
177
+ f"{self.name} {command_name}",
178
+ command_args
179
+ ):
180
+ return 1
181
+
182
+ try:
183
+ result = command['func'](**self._parse_args(command, command_args))
184
+
185
+ if self.parent:
186
+ self.parent.plugin_manager.after_command(
187
+ f"{self.name} {command_name}",
188
+ command_args,
189
+ result
190
+ )
191
+
192
+ # Handle command chaining
193
+ if self.chain and result is not None:
194
+ return result
195
+
196
+ return 0
197
+
198
+ except Exception as e:
199
+ if self.parent:
200
+ self.parent.plugin_manager.on_error(
201
+ f"{self.name} {command_name}",
202
+ e
203
+ )
204
+ if getattr(self.parent, 'debug', False):
205
+ raise
206
+ format_error(str(e))
207
+ return 1
208
+
209
+ except Exception as e:
210
+ if getattr(self.parent, 'debug', False):
211
+ raise
212
+ format_error(str(e))
213
+ return 1
214
+
215
+ def _parse_args(self, command: Dict[str, Any], args: List[str]) -> Dict[str, Any]:
216
+ """Parse command arguments."""
217
+ # Use parent CLI's argument parser if available
218
+ if self.parent:
219
+ return self.parent._parse_args(command, args)
220
+
221
+ # Fallback to basic argument parsing
222
+ from ..utils.parsing import parse_args
223
+ return parse_args(args)
224
+
225
+ def _print_help(self) -> None:
226
+ """Print group help message."""
227
+ console.print(f"\n[bold]{self.name}[/] - {self.help or ''}")
228
+
229
+ console.print("\n[bold]Commands:[/]")
230
+ for name, cmd in self.commands.items():
231
+ if isinstance(cmd, Group):
232
+ console.print(f" {name} [group]")
233
+ if cmd.help:
234
+ console.print(f" {cmd.help}")
235
+ elif not cmd.get('hidden', False):
236
+ console.print(f" {name:20} {cmd['help'] or ''}")
237
+
238
+ console.print("\nUse -h or --help with any command for more info")
239
+
240
+ def __repr__(self) -> str:
241
+ return f"<Group name={self.name}>"
@@ -0,0 +1,28 @@
1
+ """Decorators for SwiftCLI."""
2
+
3
+ from .command import command, group, argument, flag, pass_context
4
+ from .options import option, envvar, config_file, version_option, help_option
5
+ from .output import table_output, progress, panel_output, format_output, pager_output
6
+
7
+ __all__ = [
8
+ # Command decorators
9
+ 'command',
10
+ 'group',
11
+ 'argument',
12
+ 'flag',
13
+ 'pass_context',
14
+
15
+ # Option decorators
16
+ 'option',
17
+ 'envvar',
18
+ 'config_file',
19
+ 'version_option',
20
+ 'help_option',
21
+
22
+ # Output decorators
23
+ 'table_output',
24
+ 'progress',
25
+ 'panel_output',
26
+ 'format_output',
27
+ 'pager_output'
28
+ ]