janito 3.2.0__py3-none-any.whl → 3.3.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 (166) hide show
  1. janito/README.md +0 -3
  2. janito/cli/chat_mode/bindings.py +0 -26
  3. janito/cli/chat_mode/session.py +1 -12
  4. janito/cli/chat_mode/shell/commands/security/allowed_sites.py +33 -47
  5. janito/cli/cli_commands/list_plugins.py +8 -13
  6. janito/cli/core/model_guesser.py +24 -40
  7. janito/cli/prompt_core.py +9 -20
  8. janito/i18n/it.py +46 -46
  9. janito/llm/agent.py +16 -32
  10. janito/llm/driver.py +0 -8
  11. janito/{plugin_system → plugin_system_backup_20250825_070018}/core_loader.py +3 -76
  12. janito/{plugin_system → plugin_system_backup_20250825_070018}/core_loader_fixed.py +3 -79
  13. janito/plugins/__init__.py +21 -29
  14. janito/plugins/__main__.py +85 -0
  15. janito/plugins/base.py +57 -0
  16. janito/plugins/builtin.py +1 -1
  17. janito/plugins/core/filemanager/tools/copy_file.py +25 -1
  18. janito/plugins/core/filemanager/tools/create_directory.py +28 -1
  19. janito/plugins/core/filemanager/tools/create_file.py +27 -3
  20. janito/plugins/core/filemanager/tools/delete_text_in_file.py +1 -0
  21. janito/plugins/core/imagedisplay/plugin.py +1 -1
  22. janito/plugins/core_loader.py +144 -0
  23. janito/plugins/discovery.py +3 -3
  24. janito/plugins/example_plugin.py +1 -1
  25. janito/plugins/manager.py +1 -1
  26. janito/plugins_backup_20250825_070018/__init__.py +36 -0
  27. janito/{plugins → plugins_backup_20250825_070018}/auto_loader.py +11 -12
  28. janito/plugins_backup_20250825_070018/builtin.py +102 -0
  29. janito/plugins_backup_20250825_070018/config.py +84 -0
  30. janito/plugins_backup_20250825_070018/core/__init__.py +7 -0
  31. janito/plugins_backup_20250825_070018/core/codeanalyzer/__init__.py +43 -0
  32. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/__init__.py +1 -0
  33. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/core.py +122 -0
  34. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/__init__.py +1 -0
  35. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/core.py +205 -0
  36. janito/plugins_backup_20250825_070018/core/filemanager/__init__.py +124 -0
  37. janito/plugins_backup_20250825_070018/core/filemanager/tools/copy_file.py +87 -0
  38. janito/plugins_backup_20250825_070018/core/filemanager/tools/create_directory.py +70 -0
  39. janito/plugins_backup_20250825_070018/core/filemanager/tools/create_file.py +87 -0
  40. janito/plugins_backup_20250825_070018/core/filemanager/tools/delete_text_in_file.py +135 -0
  41. janito/plugins_backup_20250825_070018/core/filemanager/tools/find_files.py +143 -0
  42. janito/plugins_backup_20250825_070018/core/filemanager/tools/move_file.py +131 -0
  43. janito/plugins_backup_20250825_070018/core/filemanager/tools/read_files.py +58 -0
  44. janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_directory.py +55 -0
  45. janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_file.py +58 -0
  46. janito/plugins_backup_20250825_070018/core/filemanager/tools/replace_text_in_file.py +270 -0
  47. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/__init__.py +1 -0
  48. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/core.py +114 -0
  49. janito/plugins_backup_20250825_070018/core/filemanager/tools/view_file.py +172 -0
  50. janito/plugins_backup_20250825_070018/core/imagedisplay/__init__.py +14 -0
  51. janito/plugins_backup_20250825_070018/core/imagedisplay/plugin.py +51 -0
  52. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/__init__.py +1 -0
  53. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image.py +83 -0
  54. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image_grid.py +84 -0
  55. janito/plugins_backup_20250825_070018/core/system/__init__.py +23 -0
  56. janito/plugins_backup_20250825_070018/core/system/tools/run_bash_command.py +183 -0
  57. janito/plugins_backup_20250825_070018/core/system/tools/run_powershell_command.py +218 -0
  58. janito/plugins_backup_20250825_070018/core_adapter.py +55 -0
  59. janito/plugins_backup_20250825_070018/dev/__init__.py +7 -0
  60. janito/plugins_backup_20250825_070018/dev/pythondev/__init__.py +37 -0
  61. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_code_run.py +172 -0
  62. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_command_run.py +171 -0
  63. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_file_run.py +172 -0
  64. janito/plugins_backup_20250825_070018/dev/visualization/__init__.py +23 -0
  65. janito/plugins_backup_20250825_070018/dev/visualization/tools/read_chart.py +259 -0
  66. janito/plugins_backup_20250825_070018/discovery.py +289 -0
  67. janito/{plugins → plugins_backup_20250825_070018}/discovery_core.py +9 -14
  68. janito/plugins_backup_20250825_070018/example_plugin.py +108 -0
  69. janito/plugins_backup_20250825_070018/manager.py +243 -0
  70. janito/{plugins → plugins_backup_20250825_070018}/tools/core_tools_plugin.py +10 -9
  71. janito/{plugins → plugins_backup_20250825_070018}/tools/create_file.py +2 -2
  72. janito/{plugins → plugins_backup_20250825_070018}/tools/delete_text_in_file.py +1 -0
  73. janito/plugins_backup_20250825_070018/tools/get_file_outline/java_outline.py +47 -0
  74. janito/plugins_backup_20250825_070018/tools/get_file_outline/markdown_outline.py +14 -0
  75. janito/plugins_backup_20250825_070018/tools/get_file_outline/python_outline.py +303 -0
  76. janito/plugins_backup_20250825_070018/tools/get_file_outline/search_outline.py +36 -0
  77. janito/plugins_backup_20250825_070018/tools/search_text/match_lines.py +67 -0
  78. janito/plugins_backup_20250825_070018/tools/search_text/pattern_utils.py +73 -0
  79. janito/plugins_backup_20250825_070018/tools/search_text/traverse_directory.py +145 -0
  80. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/css_validator.py +35 -0
  81. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/html_validator.py +100 -0
  82. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/jinja2_validator.py +50 -0
  83. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/js_validator.py +27 -0
  84. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/json_validator.py +6 -0
  85. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/markdown_validator.py +109 -0
  86. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/ps1_validator.py +32 -0
  87. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/python_validator.py +5 -0
  88. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/xml_validator.py +11 -0
  89. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/yaml_validator.py +6 -0
  90. janito/plugins_backup_20250825_070018/ui/__init__.py +7 -0
  91. janito/plugins_backup_20250825_070018/ui/userinterface/__init__.py +16 -0
  92. janito/plugins_backup_20250825_070018/ui/userinterface/tools/ask_user.py +110 -0
  93. janito/plugins_backup_20250825_070018/web/__init__.py +7 -0
  94. janito/plugins_backup_20250825_070018/web/webtools/__init__.py +33 -0
  95. janito/plugins_backup_20250825_070018/web/webtools/tools/fetch_url.py +458 -0
  96. janito/plugins_backup_20250825_070018/web/webtools/tools/open_html_in_browser.py +51 -0
  97. janito/plugins_backup_20250825_070018/web/webtools/tools/open_url.py +37 -0
  98. janito/providers/__init__.py +0 -1
  99. janito/tools/base.py +31 -1
  100. janito/tools/cli_initializer.py +1 -1
  101. janito/tools/function_adapter.py +176 -0
  102. janito/tools/initialize.py +1 -1
  103. janito/tools/loop_protection_decorator.py +117 -114
  104. janito/tools/tool_base.py +142 -114
  105. janito/tools/tools_schema.py +12 -6
  106. {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/METADATA +1 -1
  107. {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/RECORD +160 -95
  108. janito/llm/cancellation_manager.py +0 -63
  109. janito/llm/enter_cancellation.py +0 -107
  110. janito/plugins/core_adapter.py +0 -131
  111. janito/providers/together/__init__.py +0 -1
  112. janito/providers/together/model_info.py +0 -69
  113. janito/providers/together/provider.py +0 -108
  114. /janito/{plugin_system → plugin_system_backup_20250825_070018}/__init__.py +0 -0
  115. /janito/{plugin_system → plugin_system_backup_20250825_070018}/base.py +0 -0
  116. /janito/{plugins → plugins_backup_20250825_070018}/auto_loader_fixed.py +0 -0
  117. /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/get_file_outline/java_outline.py +0 -0
  118. /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/get_file_outline/markdown_outline.py +0 -0
  119. /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/get_file_outline/python_outline.py +0 -0
  120. /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/get_file_outline/search_outline.py +0 -0
  121. /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/search_text/match_lines.py +0 -0
  122. /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/search_text/pattern_utils.py +0 -0
  123. /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/search_text/traverse_directory.py +0 -0
  124. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/css_validator.py +0 -0
  125. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/html_validator.py +0 -0
  126. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/jinja2_validator.py +0 -0
  127. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/js_validator.py +0 -0
  128. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/json_validator.py +0 -0
  129. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/markdown_validator.py +0 -0
  130. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/ps1_validator.py +0 -0
  131. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/python_validator.py +0 -0
  132. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/xml_validator.py +0 -0
  133. /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/yaml_validator.py +0 -0
  134. /janito/{plugins → plugins_backup_20250825_070018}/tools/__init__.py +0 -0
  135. /janito/{plugins → plugins_backup_20250825_070018}/tools/ask_user.py +0 -0
  136. /janito/{plugins → plugins_backup_20250825_070018}/tools/copy_file.py +0 -0
  137. /janito/{plugins → plugins_backup_20250825_070018}/tools/create_directory.py +0 -0
  138. /janito/{plugins → plugins_backup_20250825_070018}/tools/decorators.py +0 -0
  139. /janito/{plugins → plugins_backup_20250825_070018}/tools/fetch_url.py +0 -0
  140. /janito/{plugins → plugins_backup_20250825_070018}/tools/find_files.py +0 -0
  141. /janito/{plugins → plugins_backup_20250825_070018}/tools/get_file_outline/__init__.py +0 -0
  142. /janito/{plugins → plugins_backup_20250825_070018}/tools/get_file_outline/core.py +0 -0
  143. /janito/{plugins → plugins_backup_20250825_070018}/tools/move_file.py +0 -0
  144. /janito/{plugins → plugins_backup_20250825_070018}/tools/open_html_in_browser.py +0 -0
  145. /janito/{plugins → plugins_backup_20250825_070018}/tools/open_url.py +0 -0
  146. /janito/{plugins → plugins_backup_20250825_070018}/tools/python_code_run.py +0 -0
  147. /janito/{plugins → plugins_backup_20250825_070018}/tools/python_command_run.py +0 -0
  148. /janito/{plugins → plugins_backup_20250825_070018}/tools/python_file_run.py +0 -0
  149. /janito/{plugins → plugins_backup_20250825_070018}/tools/read_chart.py +0 -0
  150. /janito/{plugins → plugins_backup_20250825_070018}/tools/read_files.py +0 -0
  151. /janito/{plugins → plugins_backup_20250825_070018}/tools/remove_directory.py +0 -0
  152. /janito/{plugins → plugins_backup_20250825_070018}/tools/remove_file.py +0 -0
  153. /janito/{plugins → plugins_backup_20250825_070018}/tools/replace_text_in_file.py +0 -0
  154. /janito/{plugins → plugins_backup_20250825_070018}/tools/run_bash_command.py +0 -0
  155. /janito/{plugins → plugins_backup_20250825_070018}/tools/run_powershell_command.py +0 -0
  156. /janito/{plugins → plugins_backup_20250825_070018}/tools/search_text/__init__.py +0 -0
  157. /janito/{plugins → plugins_backup_20250825_070018}/tools/search_text/core.py +0 -0
  158. /janito/{plugins → plugins_backup_20250825_070018}/tools/show_image.py +0 -0
  159. /janito/{plugins → plugins_backup_20250825_070018}/tools/show_image_grid.py +0 -0
  160. /janito/{plugins → plugins_backup_20250825_070018}/tools/validate_file_syntax/__init__.py +0 -0
  161. /janito/{plugins → plugins_backup_20250825_070018}/tools/validate_file_syntax/core.py +0 -0
  162. /janito/{plugins → plugins_backup_20250825_070018}/tools/view_file.py +0 -0
  163. {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/WHEEL +0 -0
  164. {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/entry_points.txt +0 -0
  165. {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/licenses/LICENSE +0 -0
  166. {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,8 @@ from pathlib import Path
11
11
  from typing import Optional, List, Type
12
12
 
13
13
  from janito.plugin_system.base import Plugin, PluginMetadata
14
- from janito.tools.tool_base import ToolBase, ToolPermissions
14
+ from janito.tools.function_adapter import create_function_tool
15
+ from janito.tools.tool_base import ToolBase
15
16
 
16
17
 
17
18
  class CorePlugin(Plugin):
@@ -36,89 +37,12 @@ class CorePlugin(Plugin):
36
37
  def get_tools(self) -> List[Type[ToolBase]]:
37
38
  return self._tool_classes
38
39
 
39
- def _create_tool_class(self, func):
40
- """Create a ToolBase class from a function."""
41
- resolved_tool_name = getattr(func, "tool_name", func.__name__)
42
-
43
- # Create a proper tool class with explicit parameters and documentation
44
- import inspect
45
- from typing import get_type_hints
46
-
47
- func_sig = inspect.signature(func)
48
- type_hints = get_type_hints(func)
49
-
50
- # Build parameter definitions for the run method
51
- param_defs = []
52
- param_docs = []
53
- for name, param in func_sig.parameters.items():
54
- type_hint = type_hints.get(name, str)
55
- if param.default == inspect.Parameter.empty:
56
- param_defs.append(f"{name}: {type_hint.__name__}")
57
- else:
58
- param_defs.append(f"{name}: {type_hint.__name__} = {repr(param.default)}")
59
-
60
- # Add parameter documentation
61
- param_docs.append(f" {name}: {type_hint.__name__} - Parameter {name}")
62
-
63
- # Get function docstring or create one
64
- func_doc = func.__doc__ or f"Execute {resolved_tool_name} tool"
65
-
66
- # Create the tool class with proper signature and documentation
67
- exec_globals = {
68
- 'ToolBase': ToolBase,
69
- 'ToolPermissions': ToolPermissions,
70
- 'func': func,
71
- 'inspect': inspect,
72
- 'str': str,
73
- 'List': list,
74
- 'Dict': dict,
75
- 'Optional': type(None),
76
- }
77
-
78
- param_docs_str = '\n'.join(param_docs)
79
-
80
- class_def = f'''
81
- class DynamicTool(ToolBase):
82
- """
83
- {func_doc}
84
-
85
- Parameters:
86
- {param_docs_str}
87
-
88
- Returns:
89
- str: Execution result
90
- """
91
- tool_name = "{resolved_tool_name}"
92
- permissions = ToolPermissions(read=True, write=True, execute=True)
93
-
94
- def __init__(self):
95
- super().__init__()
96
-
97
- def run(self, {', '.join(param_defs)}) -> str:
98
- kwargs = locals()
99
- sig = inspect.signature(func)
100
-
101
- # Filter kwargs to only include parameters the function accepts
102
- filtered_kwargs = {{}}
103
- for name, param in sig.parameters.items():
104
- if name in kwargs and kwargs[name] is not None:
105
- filtered_kwargs[name] = kwargs[name]
106
-
107
- result = func(**filtered_kwargs)
108
- return str(result) if result is not None else ""
109
- '''
110
-
111
- exec(class_def, exec_globals)
112
- return exec_globals['DynamicTool']
113
-
114
- return DynamicTool
115
-
116
40
  def initialize(self):
117
41
  """Initialize by creating tool classes."""
118
42
  self._tool_classes = []
119
43
  for tool_func in self._tools:
120
44
  if callable(tool_func):
121
- tool_class = self._create_tool_class(tool_func)
45
+ tool_class = create_function_tool(tool_func)
122
46
  self._tool_classes.append(tool_class)
123
47
 
124
48
 
@@ -1,36 +1,28 @@
1
1
  """
2
- Plugin System for Development Tools
2
+ Unified Plugin System for Janito
3
3
 
4
- This package organizes all available tools into logical plugin groups
5
- for easier discovery and usage.
4
+ This package provides a clean, unified plugin architecture for janito.
6
5
  """
7
6
 
8
7
  __version__ = "1.0.0"
9
8
  __author__ = "Development Assistant"
10
9
 
11
- from .core import filemanager, codeanalyzer, system, imagedisplay
12
- from .web import webtools
13
- from .dev import pythondev, visualization
14
- from .ui import userinterface
15
-
16
- # Plugin registry
17
- PLUGINS = {
18
- "core.filemanager": filemanager,
19
- "core.codeanalyzer": codeanalyzer,
20
- "core.system": system,
21
- "core.imagedisplay": imagedisplay,
22
- "web.webtools": webtools,
23
- "dev.pythondev": pythondev,
24
- "dev.visualization": visualization,
25
- "ui.userinterface": userinterface,
26
- }
27
-
28
-
29
- def list_plugins():
30
- """Return all available plugins"""
31
- return list(PLUGINS.keys())
32
-
33
-
34
- def get_plugin(name):
35
- """Get a specific plugin by name"""
36
- return PLUGINS.get(name)
10
+ # Import core components
11
+ from .base import Plugin, PluginMetadata, PluginResource
12
+ from .manager import PluginManager
13
+ from .discovery import discover_plugins, list_available_plugins
14
+ from .config import load_plugins_config, save_plugins_config
15
+ from .builtin import BuiltinPluginRegistry, load_builtin_plugin
16
+
17
+ __all__ = [
18
+ "Plugin",
19
+ "PluginMetadata",
20
+ "PluginResource",
21
+ "PluginManager",
22
+ "discover_plugins",
23
+ "list_available_plugins",
24
+ "load_plugins_config",
25
+ "save_plugins_config",
26
+ "BuiltinPluginRegistry",
27
+ "load_builtin_plugin",
28
+ ]
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Plugin system CLI entry point.
4
+ """
5
+
6
+ import argparse
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from .manager import PluginManager
11
+ from .discovery import list_available_plugins
12
+ from .core_loader import get_core_plugins
13
+
14
+
15
+ def list_plugins():
16
+ """List all available plugins."""
17
+ print("📋 Available Plugins:")
18
+ print("=" * 50)
19
+
20
+ # Get available plugins
21
+ available = list_available_plugins()
22
+
23
+ # Get core plugins
24
+ core_plugins = get_core_plugins()
25
+
26
+ if available:
27
+ print("\n🔌 Available Plugins:")
28
+ for plugin in sorted(available):
29
+ if plugin in core_plugins:
30
+ print(f" ✅ {plugin} (core)")
31
+ else:
32
+ print(f" 🔌 {plugin}")
33
+ else:
34
+ print(" No plugins found in search paths")
35
+
36
+ print(f"\n📊 Total: {len(available)} plugins")
37
+
38
+
39
+ def list_loaded():
40
+ """List currently loaded plugins."""
41
+ print("🔧 Currently Loaded Plugins:")
42
+ print("=" * 50)
43
+
44
+ pm = PluginManager()
45
+
46
+ # Load core plugins
47
+ core_plugins = get_core_plugins()
48
+ for plugin in core_plugins:
49
+ pm.load_plugin(plugin)
50
+
51
+ loaded = pm.list_plugins()
52
+
53
+ if loaded:
54
+ for plugin in sorted(loaded):
55
+ metadata = pm.get_plugin_metadata(plugin)
56
+ if metadata:
57
+ print(f" 📦 {plugin} v{metadata.version}")
58
+ print(f" {metadata.description}")
59
+ else:
60
+ print(f" 📦 {plugin}")
61
+ else:
62
+ print(" No plugins currently loaded")
63
+
64
+ print(f"\n📊 Total: {len(loaded)} plugins loaded")
65
+
66
+
67
+ def main():
68
+ """Main CLI entry point."""
69
+ parser = argparse.ArgumentParser(description="Janito Plugin System CLI")
70
+ parser.add_argument(
71
+ "--list-plugins",
72
+ action="store_true",
73
+ help="List all loaded plugins"
74
+ )
75
+
76
+ args = parser.parse_args()
77
+
78
+ if args.list_plugins:
79
+ list_loaded()
80
+ else:
81
+ list_loaded()
82
+
83
+
84
+ if __name__ == "__main__":
85
+ main()
janito/plugins/base.py ADDED
@@ -0,0 +1,57 @@
1
+ """
2
+ Base classes for janito plugins.
3
+ """
4
+
5
+ from abc import ABC, abstractmethod
6
+ from dataclasses import dataclass
7
+ from typing import Dict, Any, List, Optional, Type
8
+
9
+ @dataclass
10
+ class PluginMetadata:
11
+ name: str
12
+ version: str
13
+ description: str
14
+ author: str
15
+ license: str = "MIT"
16
+ homepage: Optional[str] = None
17
+ dependencies: List[str] = None
18
+
19
+ def __post_init__(self):
20
+ if self.dependencies is None:
21
+ self.dependencies = []
22
+
23
+ @dataclass
24
+ class PluginResource:
25
+ name: str
26
+ type: str
27
+ description: str
28
+ schema: Optional[Dict[str, Any]] = None
29
+
30
+ class Plugin(ABC):
31
+ def __init__(self):
32
+ self.metadata: PluginMetadata = self.get_metadata()
33
+
34
+ @abstractmethod
35
+ def get_metadata(self) -> PluginMetadata:
36
+ pass
37
+
38
+ def get_tools(self):
39
+ return []
40
+
41
+ def get_commands(self):
42
+ return {}
43
+
44
+ def initialize(self):
45
+ pass
46
+
47
+ def cleanup(self):
48
+ pass
49
+
50
+ def get_config_schema(self):
51
+ return {}
52
+
53
+ def validate_config(self, config):
54
+ return True
55
+
56
+ def get_resources(self):
57
+ return []
janito/plugins/builtin.py CHANGED
@@ -7,7 +7,7 @@ with janito and available by default without requiring external installation.
7
7
 
8
8
  import importlib
9
9
  from typing import Dict, List, Optional, Type
10
- from janito.plugin_system.base import Plugin
10
+ from .base import Plugin
11
11
 
12
12
 
13
13
  class BuiltinPluginRegistry:
@@ -13,12 +13,36 @@ from janito.i18n import tr
13
13
  class CopyFileTool(ToolBase):
14
14
  """
15
15
  Copy one or more files to a target directory, or copy a single file to a new file.
16
- Args:
16
+
17
+ Parameters:
17
18
  sources (str): Space-separated path(s) to the file(s) to copy.
18
19
  For multiple sources, provide a single string with paths separated by spaces.
19
20
  target (str): Destination path. If copying multiple sources, this must be an existing directory.
20
21
  overwrite (bool, optional): Overwrite existing files. Default: False.
21
22
  Recommended only after reading the file to be overwritten.
23
+ content (str): File content to write or process
24
+ recursive (bool): Whether to process directories recursively
25
+ from_line (int): Starting line number for file reading
26
+ to_line (int): Ending line number for file reading
27
+ search_text (str): Text to search for in files
28
+ replacement_text (str): Text to replace search matches with
29
+ use_regex (bool): Whether to treat search as regex pattern
30
+ case_sensitive (bool): Whether search should be case sensitive
31
+ max_depth (int): Maximum directory depth to search
32
+ include_gitignored (bool): Whether to include .gitignored files
33
+ timeout (int): Timeout in seconds for operations
34
+ require_confirmation (bool): Whether to require user confirmation
35
+ data (dict): Chart data for visualization tools
36
+ title (str): Chart title
37
+ width (int): Chart width in pixels
38
+ height (int): Chart height in pixels
39
+ query (str): Search query for text search
40
+ paths (str): Directory or file paths to search in
41
+ src_path (str): Source path for move operations
42
+ dest_path (str): Destination path for move operations
43
+ code (str): Python code to execute
44
+ pattern (str): File pattern to match (e.g., '*.py')
45
+
22
46
  Returns:
23
47
  str: Status string for each copy operation.
24
48
  """
@@ -12,8 +12,35 @@ from janito.tools.path_utils import expand_path
12
12
  class CreateDirectoryTool(ToolBase):
13
13
  """
14
14
  Create a new directory at the specified path.
15
- Args:
15
+
16
+ Parameters:
16
17
  path (str): Path for the new directory.
18
+ content (str): File content to write or process
19
+ overwrite (bool): Whether to overwrite existing files (default: False)
20
+ sources (str): Source file(s) to copy from
21
+ target (str): Destination path for copy operations
22
+ recursive (bool): Whether to process directories recursively
23
+ from_line (int): Starting line number for file reading
24
+ to_line (int): Ending line number for file reading
25
+ search_text (str): Text to search for in files
26
+ replacement_text (str): Text to replace search matches with
27
+ use_regex (bool): Whether to treat search as regex pattern
28
+ case_sensitive (bool): Whether search should be case sensitive
29
+ max_depth (int): Maximum directory depth to search
30
+ include_gitignored (bool): Whether to include .gitignored files
31
+ timeout (int): Timeout in seconds for operations
32
+ require_confirmation (bool): Whether to require user confirmation
33
+ data (dict): Chart data for visualization tools
34
+ title (str): Chart title
35
+ width (int): Chart width in pixels
36
+ height (int): Chart height in pixels
37
+ query (str): Search query for text search
38
+ paths (str): Directory or file paths to search in
39
+ src_path (str): Source path for move operations
40
+ dest_path (str): Destination path for move operations
41
+ code (str): Python code to execute
42
+ pattern (str): File pattern to match (e.g., '*.py')
43
+
17
44
  Returns:
18
45
  str: Status message indicating the result. Example:
19
46
  - "5c5 Successfully created the directory at ..."
@@ -16,10 +16,34 @@ class CreateFileTool(ToolBase):
16
16
  """
17
17
  Create a new file with the given content.
18
18
 
19
- Args:
19
+ Parameters:
20
20
  path (str): Path to the file to create.
21
21
  content (str): Content to write to the file.
22
22
  overwrite (bool, optional): Overwrite existing file if True. Default: False. Recommended only after reading the file to be overwritten.
23
+ sources (str): Source file(s) to copy from
24
+ target (str): Destination path for copy operations
25
+ recursive (bool): Whether to process directories recursively
26
+ from_line (int): Starting line number for file reading
27
+ to_line (int): Ending line number for file reading
28
+ search_text (str): Text to search for in files
29
+ replacement_text (str): Text to replace search matches with
30
+ use_regex (bool): Whether to treat search as regex pattern
31
+ case_sensitive (bool): Whether search should be case sensitive
32
+ max_depth (int): Maximum directory depth to search
33
+ include_gitignored (bool): Whether to include .gitignored files
34
+ timeout (int): Timeout in seconds for operations
35
+ require_confirmation (bool): Whether to require user confirmation
36
+ data (dict): Chart data for visualization tools
37
+ title (str): Chart title
38
+ width (int): Chart width in pixels
39
+ height (int): Chart height in pixels
40
+ query (str): Search query for text search
41
+ paths (str): Directory or file paths to search in
42
+ src_path (str): Source path for move operations
43
+ dest_path (str): Destination path for move operations
44
+ code (str): Python code to execute
45
+ pattern (str): File pattern to match (e.g., '*.py')
46
+
23
47
  Returns:
24
48
  str: Status message indicating the result. Example:
25
49
  - "✅ Successfully created the file at ..."
@@ -27,13 +51,13 @@ class CreateFileTool(ToolBase):
27
51
  Note: Syntax validation is automatically performed after this operation.
28
52
 
29
53
  Security: This tool includes loop protection to prevent excessive file creation operations.
30
- Protection: Prevents repeated create calls for the same file path within a short window (1 allowed per 10 seconds).
54
+ Maximum 5 calls per 10 seconds for the same file path.
31
55
  """
32
56
 
33
57
  permissions = ToolPermissions(write=True)
34
58
  tool_name = "create_file"
35
59
 
36
- @protect_against_loops(max_calls=1, time_window=10.0, key_field="path")
60
+ @protect_against_loops(max_calls=5, time_window=10.0, key_field="path")
37
61
  def run(self, path: str, content: str, overwrite: bool = False) -> str:
38
62
  path = expand_path(path)
39
63
  disp_path = display_path(path)
@@ -15,6 +15,7 @@ class DeleteTextInFileTool(ToolBase):
15
15
  path (str): Path to the file to modify.
16
16
  start_marker (str): The starting delimiter string.
17
17
  end_marker (str): The ending delimiter string.
18
+ backup (bool, optional): Deprecated. No backups are created anymore and this flag is ignored. Defaults to False.
18
19
 
19
20
  Returns:
20
21
  str: Status message indicating the result.
@@ -4,7 +4,7 @@ Image Display Plugin implementation.
4
4
 
5
5
  from typing import Dict, Any, List, Type
6
6
 
7
- from janito.plugin_system.base import Plugin, PluginMetadata
7
+ from ...base import Plugin, PluginMetadata
8
8
  from janito.tools.tool_base import ToolBase
9
9
  from .tools.show_image import ShowImageTool
10
10
  from .tools.show_image_grid import ShowImageGridTool
@@ -0,0 +1,144 @@
1
+ """
2
+ Fixed core plugin loader.
3
+
4
+ This module provides a working implementation to load core plugins
5
+ by directly using the Plugin base class properly.
6
+ """
7
+
8
+ import importlib
9
+ import importlib.util
10
+ import sys
11
+ from pathlib import Path
12
+ from typing import Optional, List, Type
13
+
14
+ from .base import Plugin, PluginMetadata
15
+ from janito.tools.function_adapter import create_function_tool
16
+ from janito.tools.tool_base import ToolBase
17
+
18
+
19
+ class CorePlugin(Plugin):
20
+ """Working core plugin implementation."""
21
+
22
+ def __init__(self, name: str, description: str, tools: list):
23
+ self._plugin_name = name
24
+ self._description = description
25
+ self._tools = tools
26
+ self._tool_classes = []
27
+ super().__init__() # Call super after setting attributes
28
+
29
+ def get_metadata(self) -> PluginMetadata:
30
+ return PluginMetadata(
31
+ name=self._plugin_name,
32
+ version="1.0.0",
33
+ description=self._description,
34
+ author="Janito",
35
+ license="MIT",
36
+ )
37
+
38
+ def get_tools(self) -> List[Type[ToolBase]]:
39
+ return self._tool_classes
40
+
41
+ def initialize(self):
42
+ """Initialize by creating tool classes."""
43
+ self._tool_classes = []
44
+ for tool_func in self._tools:
45
+ if callable(tool_func):
46
+ tool_class = create_function_tool(tool_func)
47
+ self._tool_classes.append(tool_class)
48
+
49
+
50
+ def load_core_plugin(plugin_name: str) -> Optional[Plugin]:
51
+ """
52
+ Load a core plugin by name.
53
+
54
+ Args:
55
+ plugin_name: Name of the plugin (e.g., 'core.filemanager')
56
+
57
+ Returns:
58
+ Plugin instance if loaded successfully
59
+ """
60
+ try:
61
+ # Parse plugin name
62
+ if "." not in plugin_name:
63
+ return None
64
+
65
+ parts = plugin_name.split(".")
66
+ if len(parts) != 2:
67
+ return None
68
+
69
+ package_name, submodule_name = parts
70
+
71
+ # Handle imagedisplay specially
72
+ if plugin_name == "core.imagedisplay":
73
+ # Import the actual plugin class
74
+ try:
75
+ # Use dynamic import to avoid circular dependency
76
+ plugin_module = importlib.import_module(
77
+ "janito.plugins.core.imagedisplay.plugin"
78
+ )
79
+ return plugin_module.ImageDisplayPlugin()
80
+ except ImportError as e:
81
+ print(f"Failed to load imagedisplay: {e}")
82
+ return None
83
+
84
+ # Build path to plugin
85
+ plugin_path = (
86
+ Path("janito/plugins") / package_name / submodule_name / "__init__.py"
87
+ )
88
+ if not plugin_path.exists():
89
+ return None
90
+
91
+ # Load the module
92
+ spec = importlib.util.spec_from_file_location(plugin_name, plugin_path)
93
+ if spec is None or spec.loader is None:
94
+ return None
95
+
96
+ module = importlib.util.module_from_spec(spec)
97
+ spec.loader.exec_module(module)
98
+
99
+ # Get plugin info
100
+ name = getattr(module, "__plugin_name__", plugin_name)
101
+ description = getattr(
102
+ module, "__plugin_description__", f"Core plugin: {plugin_name}"
103
+ )
104
+ tools = getattr(module, "__plugin_tools__", [])
105
+
106
+ if not tools:
107
+ return None
108
+
109
+ # Filter out None values and ensure all tools have tool_name
110
+ valid_tools = []
111
+ for tool in tools:
112
+ if tool is not None:
113
+ if not hasattr(tool, "tool_name"):
114
+ tool.tool_name = tool.__name__
115
+ valid_tools.append(tool)
116
+
117
+ if not valid_tools:
118
+ return None
119
+
120
+ # Create plugin
121
+ plugin = CorePlugin(name, description, valid_tools)
122
+ plugin.initialize()
123
+ return plugin
124
+
125
+ except Exception as e:
126
+ print(f"Error loading core plugin {plugin_name}: {e}")
127
+ return None
128
+
129
+
130
+ def get_core_plugins() -> list:
131
+ """Get list of all available core plugins."""
132
+ core_plugins = [
133
+ "core.filemanager",
134
+ "core.codeanalyzer",
135
+ "core.system",
136
+ "core.imagedisplay",
137
+ "dev.pythondev",
138
+ "dev.visualization",
139
+ "ui.userinterface",
140
+ "web.webtools",
141
+ ]
142
+
143
+ # All core plugins are always available
144
+ return core_plugins
@@ -31,9 +31,9 @@ from pathlib import Path
31
31
  from typing import Optional, List
32
32
  import logging
33
33
 
34
- from janito.plugin_system.base import Plugin
34
+ from .base import Plugin
35
35
  from .builtin import load_builtin_plugin, BuiltinPluginRegistry
36
- from janito.plugin_system.core_loader import load_core_plugin
36
+ from .core_loader import load_core_plugin
37
37
 
38
38
  logger = logging.getLogger(__name__)
39
39
 
@@ -157,7 +157,7 @@ def _load_plugin_from_file(
157
157
 
158
158
  # Check for package-based plugin with __plugin_name__ metadata
159
159
  if hasattr(module, "__plugin_name__"):
160
- from janito.plugin_system.base import PluginMetadata
160
+ from .base import PluginMetadata
161
161
 
162
162
  # Create a dynamic plugin class
163
163
  class PackagePlugin(Plugin):
@@ -2,7 +2,7 @@
2
2
  Example plugin demonstrating the plugin system.
3
3
  """
4
4
 
5
- from janito.plugin_system.base import Plugin, PluginMetadata, PluginResource
5
+ from .base import Plugin, PluginMetadata, PluginResource
6
6
  from janito.tools.tool_base import ToolBase, ToolPermissions
7
7
  from typing import Dict, Any
8
8
 
janito/plugins/manager.py CHANGED
@@ -10,7 +10,7 @@ from pathlib import Path
10
10
  from typing import Dict, List, Optional, Any
11
11
  import logging
12
12
 
13
- from janito.plugin_system.base import Plugin, PluginMetadata
13
+ from .base import Plugin, PluginMetadata
14
14
  from .discovery import discover_plugins
15
15
  from .config import load_plugins_config, get_user_plugins_dir
16
16
  from .builtin import BuiltinPluginRegistry, load_builtin_plugin
@@ -0,0 +1,36 @@
1
+ """
2
+ Plugin System for Development Tools
3
+
4
+ This package organizes all available tools into logical plugin groups
5
+ for easier discovery and usage.
6
+ """
7
+
8
+ __version__ = "1.0.0"
9
+ __author__ = "Development Assistant"
10
+
11
+ from .core import filemanager, codeanalyzer, system, imagedisplay
12
+ from .web import webtools
13
+ from .dev import pythondev, visualization
14
+ from .ui import userinterface
15
+
16
+ # Plugin registry
17
+ PLUGINS = {
18
+ "core.filemanager": filemanager,
19
+ "core.codeanalyzer": codeanalyzer,
20
+ "core.system": system,
21
+ "core.imagedisplay": imagedisplay,
22
+ "web.webtools": webtools,
23
+ "dev.pythondev": pythondev,
24
+ "dev.visualization": visualization,
25
+ "ui.userinterface": userinterface,
26
+ }
27
+
28
+
29
+ def list_plugins():
30
+ """Return all available plugins"""
31
+ return list(PLUGINS.keys())
32
+
33
+
34
+ def get_plugin(name):
35
+ """Get a specific plugin by name"""
36
+ return PLUGINS.get(name)