janito 2.27.1__py3-none-any.whl → 2.28.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. janito/README.md +9 -9
  2. janito/agent/setup_agent.py +29 -16
  3. janito/cli/chat_mode/script_runner.py +1 -1
  4. janito/cli/chat_mode/session.py +17 -5
  5. janito/cli/chat_mode/session_profile_select.py +8 -2
  6. janito/cli/chat_mode/shell/commands/execute.py +4 -2
  7. janito/cli/chat_mode/shell/commands/help.py +2 -0
  8. janito/cli/chat_mode/shell/commands/privileges.py +6 -2
  9. janito/cli/chat_mode/shell/commands/provider.py +7 -4
  10. janito/cli/chat_mode/shell/commands/read.py +4 -2
  11. janito/cli/chat_mode/shell/commands/security/__init__.py +1 -1
  12. janito/cli/chat_mode/shell/commands/security/allowed_sites.py +16 -13
  13. janito/cli/chat_mode/shell/commands/security_command.py +14 -10
  14. janito/cli/chat_mode/shell/commands/tools.py +4 -2
  15. janito/cli/chat_mode/shell/commands/unrestricted.py +17 -12
  16. janito/cli/chat_mode/shell/commands/write.py +4 -2
  17. janito/cli/chat_mode/toolbar.py +4 -4
  18. janito/cli/cli_commands/enable_disable_plugin.py +48 -25
  19. janito/cli/cli_commands/list_models.py +2 -2
  20. janito/cli/cli_commands/list_plugins.py +18 -18
  21. janito/cli/cli_commands/list_profiles.py +6 -6
  22. janito/cli/cli_commands/list_providers.py +1 -1
  23. janito/cli/cli_commands/model_utils.py +45 -20
  24. janito/cli/cli_commands/ping_providers.py +10 -10
  25. janito/cli/cli_commands/set_api_key.py +5 -3
  26. janito/cli/cli_commands/show_config.py +13 -7
  27. janito/cli/cli_commands/show_system_prompt.py +13 -6
  28. janito/cli/core/getters.py +1 -0
  29. janito/cli/core/model_guesser.py +18 -15
  30. janito/cli/core/runner.py +15 -7
  31. janito/cli/core/setters.py +9 -6
  32. janito/cli/main_cli.py +15 -12
  33. janito/cli/prompt_core.py +2 -0
  34. janito/cli/prompt_setup.py +4 -4
  35. janito/cli/single_shot_mode/handler.py +2 -0
  36. janito/config_manager.py +2 -0
  37. janito/docs/GETTING_STARTED.md +9 -9
  38. janito/drivers/cerebras/__init__.py +1 -1
  39. janito/exceptions.py +6 -4
  40. janito/plugins/__init__.py +2 -2
  41. janito/plugins/base.py +48 -40
  42. janito/plugins/builtin.py +13 -9
  43. janito/plugins/config.py +16 -19
  44. janito/plugins/discovery.py +73 -66
  45. janito/plugins/manager.py +62 -60
  46. janito/provider_registry.py +10 -10
  47. janito/providers/__init__.py +1 -1
  48. janito/providers/alibaba/model_info.py +3 -5
  49. janito/providers/alibaba/provider.py +3 -1
  50. janito/providers/cerebras/__init__.py +1 -1
  51. janito/providers/cerebras/model_info.py +12 -27
  52. janito/providers/cerebras/provider.py +11 -9
  53. janito/providers/mistral/__init__.py +1 -1
  54. janito/providers/mistral/model_info.py +1 -1
  55. janito/providers/mistral/provider.py +1 -1
  56. janito/providers/moonshot/__init__.py +1 -0
  57. janito/providers/{moonshotai → moonshot}/model_info.py +3 -3
  58. janito/providers/{moonshotai → moonshot}/provider.py +8 -8
  59. janito/providers/openai/provider.py +3 -1
  60. janito/report_events.py +0 -1
  61. janito/tools/adapters/local/create_file.py +1 -1
  62. janito/tools/adapters/local/fetch_url.py +45 -29
  63. janito/tools/adapters/local/python_command_run.py +2 -1
  64. janito/tools/adapters/local/python_file_run.py +1 -0
  65. janito/tools/adapters/local/run_powershell_command.py +1 -1
  66. janito/tools/adapters/local/search_text/core.py +1 -1
  67. janito/tools/adapters/local/validate_file_syntax/jinja2_validator.py +14 -11
  68. janito/tools/base.py +4 -3
  69. janito/tools/loop_protection.py +24 -22
  70. janito/tools/path_utils.py +7 -7
  71. janito/tools/tool_base.py +0 -2
  72. janito/tools/tools_adapter.py +15 -5
  73. janito/tools/url_whitelist.py +27 -26
  74. {janito-2.27.1.dist-info → janito-2.28.0.dist-info}/METADATA +1 -1
  75. {janito-2.27.1.dist-info → janito-2.28.0.dist-info}/RECORD +79 -79
  76. janito/providers/moonshotai/__init__.py +0 -1
  77. {janito-2.27.1.dist-info → janito-2.28.0.dist-info}/WHEEL +0 -0
  78. {janito-2.27.1.dist-info → janito-2.28.0.dist-info}/entry_points.txt +0 -0
  79. {janito-2.27.1.dist-info → janito-2.28.0.dist-info}/licenses/LICENSE +0 -0
  80. {janito-2.27.1.dist-info → janito-2.28.0.dist-info}/top_level.txt +0 -0
@@ -37,36 +37,38 @@ from .builtin import load_builtin_plugin, BuiltinPluginRegistry
37
37
  logger = logging.getLogger(__name__)
38
38
 
39
39
 
40
- def discover_plugins(plugin_name: str, search_paths: List[Path] = None) -> Optional[Plugin]:
40
+ def discover_plugins(
41
+ plugin_name: str, search_paths: List[Path] = None
42
+ ) -> Optional[Plugin]:
41
43
  """
42
44
  Discover and load a plugin by name.
43
-
45
+
44
46
  Supports multiple plugin formats:
45
47
  - Single .py files
46
48
  - Python package directories
47
49
  - Package-based plugins (e.g., core.filemanager)
48
50
  - Installed Python packages
49
51
  - ZIP files containing packages
50
-
52
+
51
53
  Args:
52
54
  plugin_name: Name of the plugin to discover
53
55
  search_paths: List of directories to search for plugins
54
-
56
+
55
57
  Returns:
56
58
  Plugin instance if found, None otherwise
57
59
  """
58
60
  if search_paths is None:
59
61
  search_paths = []
60
-
62
+
61
63
  # Add default search paths
62
64
  default_paths = [
63
65
  Path.cwd() / "plugins",
64
66
  Path.home() / ".janito" / "plugins",
65
67
  Path(sys.prefix) / "share" / "janito" / "plugins",
66
68
  ]
67
-
69
+
68
70
  all_paths = search_paths + default_paths
69
-
71
+
70
72
  # Handle package-based plugins (e.g., core.filemanager)
71
73
  if "." in plugin_name:
72
74
  parts = plugin_name.split(".")
@@ -76,33 +78,33 @@ def discover_plugins(plugin_name: str, search_paths: List[Path] = None) -> Optio
76
78
  package_path = base_path / package_name / submodule_name / "__init__.py"
77
79
  if package_path.exists():
78
80
  return _load_plugin_from_file(package_path, plugin_name=plugin_name)
79
-
81
+
80
82
  plugin_path = base_path / package_name / submodule_name / "plugin.py"
81
83
  if plugin_path.exists():
82
84
  return _load_plugin_from_file(plugin_path, plugin_name=plugin_name)
83
-
85
+
84
86
  # Try to find plugin in search paths
85
87
  for base_path in all_paths:
86
88
  plugin_path = base_path / plugin_name
87
89
  if plugin_path.exists():
88
90
  return _load_plugin_from_directory(plugin_path)
89
-
91
+
90
92
  # Try as Python module
91
93
  module_path = base_path / f"{plugin_name}.py"
92
94
  if module_path.exists():
93
95
  return _load_plugin_from_file(module_path)
94
-
96
+
95
97
  # Check for builtin plugins
96
98
  builtin_plugin = load_builtin_plugin(plugin_name)
97
99
  if builtin_plugin:
98
100
  return builtin_plugin
99
-
101
+
100
102
  # Try importing as installed package
101
103
  try:
102
104
  return _load_plugin_from_package(plugin_name)
103
105
  except ImportError:
104
106
  pass
105
-
107
+
106
108
  return None
107
109
 
108
110
 
@@ -112,74 +114,78 @@ def _load_plugin_from_directory(plugin_path: Path) -> Optional[Plugin]:
112
114
  # Look for __init__.py or plugin.py
113
115
  init_file = plugin_path / "__init__.py"
114
116
  plugin_file = plugin_path / "plugin.py"
115
-
117
+
116
118
  if init_file.exists():
117
119
  return _load_plugin_from_file(init_file, plugin_name=plugin_path.name)
118
120
  elif plugin_file.exists():
119
121
  return _load_plugin_from_file(plugin_file, plugin_name=plugin_path.name)
120
-
122
+
121
123
  except Exception as e:
122
124
  logger.error(f"Failed to load plugin from directory {plugin_path}: {e}")
123
-
125
+
124
126
  return None
125
127
 
126
128
 
127
- def _load_plugin_from_file(file_path: Path, plugin_name: str = None) -> Optional[Plugin]:
129
+ def _load_plugin_from_file(
130
+ file_path: Path, plugin_name: str = None
131
+ ) -> Optional[Plugin]:
128
132
  """Load a plugin from a Python file."""
129
133
  try:
130
134
  if plugin_name is None:
131
135
  plugin_name = file_path.stem
132
-
136
+
133
137
  spec = importlib.util.spec_from_file_location(plugin_name, file_path)
134
138
  if spec is None or spec.loader is None:
135
139
  return None
136
-
140
+
137
141
  module = importlib.util.module_from_spec(spec)
138
142
  spec.loader.exec_module(module)
139
-
143
+
140
144
  # Look for Plugin class
141
145
  for attr_name in dir(module):
142
146
  attr = getattr(module, attr_name)
143
- if (isinstance(attr, type) and
144
- issubclass(attr, Plugin) and
145
- attr != Plugin):
147
+ if isinstance(attr, type) and issubclass(attr, Plugin) and attr != Plugin:
146
148
  return attr()
147
-
149
+
148
150
  # Check for package-based plugin with __plugin_name__ metadata
149
- if hasattr(module, '__plugin_name__'):
151
+ if hasattr(module, "__plugin_name__"):
150
152
  from janito.plugins.base import PluginMetadata
151
-
153
+
152
154
  # Create a dynamic plugin class
153
155
  class PackagePlugin(Plugin):
154
156
  def __init__(self):
155
157
  super().__init__()
156
158
  self._module = module
157
-
159
+
158
160
  def get_metadata(self) -> PluginMetadata:
159
161
  return PluginMetadata(
160
- name=getattr(module, '__plugin_name__', plugin_name),
161
- version=getattr(module, '__plugin_version__', '1.0.0'),
162
- description=getattr(module, '__plugin_description__', f'Package plugin: {plugin_name}'),
163
- author=getattr(module, '__plugin_author__', 'Unknown'),
164
- license=getattr(module, '__plugin_license__', 'MIT')
162
+ name=getattr(module, "__plugin_name__", plugin_name),
163
+ version=getattr(module, "__plugin_version__", "1.0.0"),
164
+ description=getattr(
165
+ module,
166
+ "__plugin_description__",
167
+ f"Package plugin: {plugin_name}",
168
+ ),
169
+ author=getattr(module, "__plugin_author__", "Unknown"),
170
+ license=getattr(module, "__plugin_license__", "MIT"),
165
171
  )
166
-
172
+
167
173
  def get_tools(self):
168
- return getattr(module, '__plugin_tools__', [])
169
-
174
+ return getattr(module, "__plugin_tools__", [])
175
+
170
176
  def initialize(self):
171
- if hasattr(module, 'initialize'):
177
+ if hasattr(module, "initialize"):
172
178
  module.initialize()
173
-
179
+
174
180
  def cleanup(self):
175
- if hasattr(module, 'cleanup'):
181
+ if hasattr(module, "cleanup"):
176
182
  module.cleanup()
177
-
183
+
178
184
  return PackagePlugin()
179
-
185
+
180
186
  except Exception as e:
181
187
  logger.error(f"Failed to load plugin from file {file_path}: {e}")
182
-
188
+
183
189
  return None
184
190
 
185
191
 
@@ -187,54 +193,52 @@ def _load_plugin_from_package(package_name: str) -> Optional[Plugin]:
187
193
  """Load a plugin from an installed package."""
188
194
  try:
189
195
  module = importlib.import_module(package_name)
190
-
196
+
191
197
  # Look for Plugin class
192
198
  for attr_name in dir(module):
193
199
  attr = getattr(module, attr_name)
194
- if (isinstance(attr, type) and
195
- issubclass(attr, Plugin) and
196
- attr != Plugin):
200
+ if isinstance(attr, type) and issubclass(attr, Plugin) and attr != Plugin:
197
201
  return attr()
198
-
202
+
199
203
  except ImportError as e:
200
204
  logger.debug(f"Could not import package {package_name}: {e}")
201
-
205
+
202
206
  return None
203
207
 
204
208
 
205
209
  def list_available_plugins(search_paths: List[Path] = None) -> List[str]:
206
210
  """
207
211
  List all available plugins in search paths.
208
-
212
+
209
213
  Scans for plugins in multiple formats:
210
214
  - .py files (excluding __init__.py)
211
215
  - Directories with __init__.py or plugin.py
212
216
  - Package directories with plugin metadata (__plugin_name__)
213
217
  - Any valid plugin structure in search paths
214
-
218
+
215
219
  Args:
216
220
  search_paths: List of directories to search for plugins
217
-
221
+
218
222
  Returns:
219
223
  List of plugin names found
220
224
  """
221
225
  if search_paths is None:
222
226
  search_paths = []
223
-
227
+
224
228
  # Add default search paths
225
229
  default_paths = [
226
230
  Path.cwd() / "plugins",
227
- Path.home() / ".janito" / "plugins",
231
+ Path.home() / ".janito" / "plugins",
228
232
  Path(sys.prefix) / "share" / "janito" / "plugins",
229
233
  ]
230
-
234
+
231
235
  all_paths = search_paths + default_paths
232
236
  plugins = []
233
-
237
+
234
238
  for base_path in all_paths:
235
239
  if not base_path.exists():
236
240
  continue
237
-
241
+
238
242
  # Look for directories with __init__.py or plugin.py
239
243
  for item in base_path.iterdir():
240
244
  if item.is_dir():
@@ -245,30 +249,33 @@ def list_available_plugins(search_paths: List[Path] = None) -> List[str]:
245
249
  if subitem.is_dir() and (subitem / "__init__.py").exists():
246
250
  try:
247
251
  import importlib.util
252
+
248
253
  spec = importlib.util.spec_from_file_location(
249
- f"{item.name}.{subitem.name}",
250
- subitem / "__init__.py"
254
+ f"{item.name}.{subitem.name}",
255
+ subitem / "__init__.py",
251
256
  )
252
257
  if spec and spec.loader:
253
258
  module = importlib.util.module_from_spec(spec)
254
259
  spec.loader.exec_module(module)
255
-
260
+
256
261
  # Check for plugin metadata
257
- if hasattr(module, '__plugin_name__'):
258
- plugins.append(getattr(module, '__plugin_name__'))
262
+ if hasattr(module, "__plugin_name__"):
263
+ plugins.append(
264
+ getattr(module, "__plugin_name__")
265
+ )
259
266
  except Exception:
260
267
  pass
261
-
268
+
262
269
  # Also check for plugin.py files
263
270
  plugin_file = item / "plugin.py"
264
271
  if plugin_file.exists():
265
272
  plugins.append(item.name)
266
-
267
- elif item.suffix == '.py' and item.stem != '__init__':
273
+
274
+ elif item.suffix == ".py" and item.stem != "__init__":
268
275
  plugins.append(item.stem)
269
-
276
+
270
277
  # Add builtin plugins
271
278
  builtin_plugins = BuiltinPluginRegistry.list_builtin_plugins()
272
279
  plugins.extend(builtin_plugins)
273
-
274
- return sorted(set(plugins))
280
+
281
+ return sorted(set(plugins))
janito/plugins/manager.py CHANGED
@@ -23,13 +23,13 @@ class PluginManager:
23
23
  """
24
24
  Manages plugin loading, registration, and lifecycle.
25
25
  """
26
-
26
+
27
27
  def __init__(self, tools_adapter: Optional[LocalToolsAdapter] = None):
28
28
  self.tools_adapter = tools_adapter or LocalToolsAdapter()
29
29
  self.plugins: Dict[str, Plugin] = {}
30
30
  self.plugin_configs: Dict[str, Dict[str, Any]] = {}
31
31
  self.plugin_paths: List[Path] = []
32
-
32
+
33
33
  def add_plugin_path(self, path: str) -> None:
34
34
  """Add a directory to search for plugins."""
35
35
  plugin_path = Path(path)
@@ -37,15 +37,17 @@ class PluginManager:
37
37
  self.plugin_paths.append(plugin_path)
38
38
  if str(plugin_path) not in sys.path:
39
39
  sys.path.insert(0, str(plugin_path))
40
-
41
- def load_plugin(self, plugin_name: str, config: Optional[Dict[str, Any]] = None) -> bool:
40
+
41
+ def load_plugin(
42
+ self, plugin_name: str, config: Optional[Dict[str, Any]] = None
43
+ ) -> bool:
42
44
  """
43
45
  Load a plugin by name.
44
-
46
+
45
47
  Args:
46
48
  plugin_name: Name of the plugin to load
47
49
  config: Optional configuration for the plugin
48
-
50
+
49
51
  Returns:
50
52
  True if plugin loaded successfully
51
53
  """
@@ -53,47 +55,47 @@ class PluginManager:
53
55
  if plugin_name in self.plugins:
54
56
  logger.warning(f"Plugin {plugin_name} already loaded")
55
57
  return True
56
-
58
+
57
59
  plugin = discover_plugins(plugin_name, self.plugin_paths)
58
60
  if not plugin:
59
61
  logger.error(f"Plugin {plugin_name} not found")
60
62
  return False
61
-
63
+
62
64
  # Store config
63
65
  if config:
64
66
  self.plugin_configs[plugin_name] = config
65
-
67
+
66
68
  # Validate config if provided
67
- if config and hasattr(plugin, 'validate_config'):
69
+ if config and hasattr(plugin, "validate_config"):
68
70
  if not plugin.validate_config(config):
69
71
  logger.error(f"Invalid configuration for plugin {plugin_name}")
70
72
  return False
71
-
73
+
72
74
  # Initialize plugin
73
75
  plugin.initialize()
74
-
76
+
75
77
  # Register tools
76
78
  tools = plugin.get_tools()
77
79
  for tool_class in tools:
78
80
  self.tools_adapter.register_tool(tool_class)
79
-
81
+
80
82
  # Store plugin
81
83
  self.plugins[plugin_name] = plugin
82
-
84
+
83
85
  logger.info(f"Successfully loaded plugin: {plugin_name}")
84
86
  return True
85
-
87
+
86
88
  except Exception as e:
87
89
  logger.error(f"Failed to load plugin {plugin_name}: {e}")
88
90
  return False
89
-
91
+
90
92
  def unload_plugin(self, plugin_name: str) -> bool:
91
93
  """
92
94
  Unload a plugin.
93
-
95
+
94
96
  Args:
95
97
  plugin_name: Name of the plugin to unload
96
-
98
+
97
99
  Returns:
98
100
  True if plugin unloaded successfully
99
101
  """
@@ -101,65 +103,65 @@ class PluginManager:
101
103
  if plugin_name not in self.plugins:
102
104
  logger.warning(f"Plugin {plugin_name} not loaded")
103
105
  return False
104
-
106
+
105
107
  plugin = self.plugins[plugin_name]
106
-
108
+
107
109
  # Unregister tools
108
110
  tools = plugin.get_tools()
109
111
  for tool_class in tools:
110
- tool_name = getattr(tool_class(), 'tool_name', None)
112
+ tool_name = getattr(tool_class(), "tool_name", None)
111
113
  if tool_name:
112
114
  self.tools_adapter.unregister_tool(tool_name)
113
-
115
+
114
116
  # Cleanup plugin
115
117
  plugin.cleanup()
116
-
118
+
117
119
  # Remove from registry
118
120
  del self.plugins[plugin_name]
119
121
  if plugin_name in self.plugin_configs:
120
122
  del self.plugin_configs[plugin_name]
121
-
123
+
122
124
  logger.info(f"Successfully unloaded plugin: {plugin_name}")
123
125
  return True
124
-
126
+
125
127
  except Exception as e:
126
128
  logger.error(f"Failed to unload plugin {plugin_name}: {e}")
127
129
  return False
128
-
130
+
129
131
  def list_plugins(self) -> List[str]:
130
132
  """Return list of loaded plugin names."""
131
133
  return list(self.plugins.keys())
132
-
134
+
133
135
  def get_plugin(self, plugin_name: str) -> Optional[Plugin]:
134
136
  """Get a loaded plugin by name."""
135
137
  return self.plugins.get(plugin_name)
136
-
138
+
137
139
  def get_plugin_metadata(self, plugin_name: str) -> Optional[PluginMetadata]:
138
140
  """Get metadata for a loaded plugin."""
139
141
  plugin = self.plugins.get(plugin_name)
140
142
  return plugin.metadata if plugin else None
141
-
143
+
142
144
  def load_plugins_from_config(self, config: Dict[str, Any]) -> None:
143
145
  """
144
146
  Load plugins from configuration.
145
-
147
+
146
148
  Args:
147
149
  config: Configuration dict with plugin settings
148
150
  """
149
- plugins_config = config.get('plugins', {})
150
-
151
+ plugins_config = config.get("plugins", {})
152
+
151
153
  # Add plugin paths
152
- for path in plugins_config.get('paths', []):
154
+ for path in plugins_config.get("paths", []):
153
155
  self.add_plugin_path(path)
154
-
156
+
155
157
  # Load plugins
156
- for plugin_name, plugin_config in plugins_config.get('load', {}).items():
158
+ for plugin_name, plugin_config in plugins_config.get("load", {}).items():
157
159
  if isinstance(plugin_config, bool):
158
160
  if plugin_config:
159
161
  self.load_plugin(plugin_name)
160
162
  else:
161
163
  self.load_plugin(plugin_name, plugin_config)
162
-
164
+
163
165
  def load_plugins_from_user_config(self) -> None:
164
166
  """
165
167
  Load plugins from user configuration directory.
@@ -167,63 +169,63 @@ class PluginManager:
167
169
  """
168
170
  config = load_plugins_config()
169
171
  self.load_plugins_from_config(config)
170
-
172
+
171
173
  def reload_plugin(self, plugin_name: str) -> bool:
172
174
  """
173
175
  Reload a plugin.
174
-
176
+
175
177
  Args:
176
178
  plugin_name: Name of the plugin to reload
177
-
179
+
178
180
  Returns:
179
181
  True if plugin reloaded successfully
180
182
  """
181
183
  config = self.plugin_configs.get(plugin_name)
182
184
  self.unload_plugin(plugin_name)
183
185
  return self.load_plugin(plugin_name, config)
184
-
186
+
185
187
  def get_loaded_plugins_info(self) -> Dict[str, Dict[str, Any]]:
186
188
  """Get information about all loaded plugins."""
187
189
  info = {}
188
190
  for name, plugin in self.plugins.items():
189
191
  info[name] = {
190
- 'metadata': plugin.metadata,
191
- 'tools': [tool.__name__ for tool in plugin.get_tools()],
192
- 'commands': list(plugin.get_commands().keys()),
193
- 'config': self.plugin_configs.get(name, {}),
194
- 'builtin': BuiltinPluginRegistry.is_builtin(name),
195
- 'resources': [
192
+ "metadata": plugin.metadata,
193
+ "tools": [tool.__name__ for tool in plugin.get_tools()],
194
+ "commands": list(plugin.get_commands().keys()),
195
+ "config": self.plugin_configs.get(name, {}),
196
+ "builtin": BuiltinPluginRegistry.is_builtin(name),
197
+ "resources": [
196
198
  {
197
- 'name': resource.name,
198
- 'type': resource.type,
199
- 'description': resource.description,
200
- 'schema': resource.schema
199
+ "name": resource.name,
200
+ "type": resource.type,
201
+ "description": resource.description,
202
+ "schema": resource.schema,
201
203
  }
202
204
  for resource in plugin.get_resources()
203
- ]
205
+ ],
204
206
  }
205
207
  return info
206
208
 
207
209
  def get_plugin_resources(self, plugin_name: str) -> List[Dict[str, Any]]:
208
210
  """
209
211
  Get resources provided by a specific plugin.
210
-
212
+
211
213
  Args:
212
214
  plugin_name: Name of the plugin
213
-
215
+
214
216
  Returns:
215
217
  List of resource dictionaries
216
218
  """
217
219
  plugin = self.plugins.get(plugin_name)
218
220
  if not plugin:
219
221
  return []
220
-
222
+
221
223
  return [
222
224
  {
223
- 'name': resource.name,
224
- 'type': resource.type,
225
- 'description': resource.description,
226
- 'schema': resource.schema
225
+ "name": resource.name,
226
+ "type": resource.type,
227
+ "description": resource.description,
228
+ "schema": resource.schema,
227
229
  }
228
230
  for resource in plugin.get_resources()
229
231
  ]
@@ -231,11 +233,11 @@ class PluginManager:
231
233
  def list_all_resources(self) -> Dict[str, List[Dict[str, Any]]]:
232
234
  """
233
235
  List all resources from all loaded plugins.
234
-
236
+
235
237
  Returns:
236
238
  Dict mapping plugin names to their resources
237
239
  """
238
240
  all_resources = {}
239
241
  for plugin_name in self.plugins:
240
242
  all_resources[plugin_name] = self.get_plugin_resources(plugin_name)
241
- return all_resources
243
+ return all_resources
@@ -39,16 +39,16 @@ class ProviderRegistry:
39
39
  if len(info) == 4 and info[3]:
40
40
  continue # skip providers flagged as not implemented
41
41
  rows.append(info[:3])
42
-
42
+
43
43
  # Group providers by openness (open-source first, then proprietary)
44
- open_providers = {'cerebras', 'deepseek', 'alibaba', 'moonshotai', 'zai'}
45
-
44
+ open_providers = {"cerebras", "deepseek", "alibaba", "moonshotai", "zai"}
45
+
46
46
  def sort_key(row):
47
47
  provider_name = row[0]
48
48
  is_open = provider_name in open_providers
49
49
  # Sort open providers alphabetically first, then proprietary alphabetically
50
50
  return (not is_open, provider_name)
51
-
51
+
52
52
  rows.sort(key=sort_key)
53
53
  return rows
54
54
 
@@ -101,21 +101,21 @@ class ProviderRegistry:
101
101
  model_specs = None
102
102
  if hasattr(model_info_mod, "MODEL_SPECS"):
103
103
  model_specs = model_info_mod.MODEL_SPECS
104
- elif hasattr(model_info_mod, "MOONSHOTAI_MODEL_SPECS"):
105
- model_specs = model_info_mod.MOONSHOTAI_MODEL_SPECS
106
-
104
+ elif hasattr(model_info_mod, "MOONSHOT_MODEL_SPECS"):
105
+ model_specs = model_info_mod.MOONSHOT_MODEL_SPECS
106
+
107
107
  if model_specs:
108
108
  default_model = getattr(provider_class, "DEFAULT_MODEL", None)
109
109
  model_names = []
110
-
110
+
111
111
  for model_key in model_specs.keys():
112
112
  if model_key == default_model:
113
113
  # Highlight the default model with color and star icon
114
114
  model_names.append(f"[bold green]⭐ {model_key}[/bold green]")
115
115
  else:
116
116
  model_names.append(model_key)
117
-
118
- if provider_name == "moonshotai":
117
+
118
+ if provider_name == "moonshot":
119
119
  return ", ".join(model_names)
120
120
  return ", ".join(model_names)
121
121
  return "-"
@@ -4,7 +4,7 @@ import janito.providers.google.provider
4
4
  import janito.providers.azure_openai.provider
5
5
  import janito.providers.anthropic.provider
6
6
  import janito.providers.deepseek.provider
7
- import janito.providers.moonshotai.provider
7
+ import janito.providers.moonshot.provider
8
8
  import janito.providers.alibaba.provider
9
9
  import janito.providers.zai.provider
10
10
  import janito.providers.cerebras.provider