janito 3.3.0__py3-none-any.whl → 3.5.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 (170) hide show
  1. janito/README.md +3 -0
  2. janito/cli/chat_mode/bindings.py +50 -0
  3. janito/cli/chat_mode/session.py +12 -1
  4. janito/cli/chat_mode/shell/commands/multi.py +5 -0
  5. janito/cli/chat_mode/shell/commands/security/allowed_sites.py +47 -33
  6. janito/cli/cli_commands/list_plugins.py +13 -8
  7. janito/cli/core/model_guesser.py +40 -24
  8. janito/cli/prompt_core.py +47 -9
  9. janito/cli/rich_terminal_reporter.py +2 -2
  10. janito/hello.txt +0 -0
  11. janito/i18n/it.py +46 -46
  12. janito/llm/agent.py +32 -16
  13. janito/llm/cancellation_manager.py +63 -0
  14. janito/llm/driver.py +8 -0
  15. janito/llm/enter_cancellation.py +107 -0
  16. janito/{plugin_system_backup_20250825_070018 → plugin_system}/core_loader.py +76 -3
  17. janito/{plugin_system_backup_20250825_070018 → plugin_system}/core_loader_fixed.py +79 -3
  18. janito/plugins/__init__.py +29 -21
  19. janito/{plugins_backup_20250825_070018 → plugins}/auto_loader.py +12 -11
  20. janito/plugins/builtin.py +1 -1
  21. janito/plugins/core/filemanager/tools/copy_file.py +1 -25
  22. janito/plugins/core/filemanager/tools/create_directory.py +1 -28
  23. janito/plugins/core/filemanager/tools/create_file.py +3 -27
  24. janito/plugins/core/filemanager/tools/delete_text_in_file.py +0 -1
  25. janito/plugins/core/imagedisplay/plugin.py +1 -1
  26. janito/plugins/core_adapter.py +131 -0
  27. janito/plugins/discovery.py +3 -3
  28. janito/{plugins_backup_20250825_070018 → plugins}/discovery_core.py +14 -9
  29. janito/plugins/example_plugin.py +1 -1
  30. janito/plugins/manager.py +1 -1
  31. janito/{plugins_backup_20250825_070018 → plugins}/tools/core_tools_plugin.py +9 -10
  32. janito/{plugins_backup_20250825_070018 → plugins}/tools/create_file.py +2 -2
  33. janito/{plugins_backup_20250825_070018 → plugins}/tools/delete_text_in_file.py +0 -1
  34. janito/providers/__init__.py +1 -0
  35. janito/providers/together/__init__.py +1 -0
  36. janito/providers/together/model_info.py +69 -0
  37. janito/providers/together/provider.py +108 -0
  38. janito/tools/base.py +1 -31
  39. janito/tools/cli_initializer.py +1 -1
  40. janito/tools/initialize.py +1 -1
  41. janito/tools/loop_protection_decorator.py +114 -117
  42. janito/tools/tool_base.py +114 -142
  43. janito/tools/tools_schema.py +6 -12
  44. janito-3.5.0.dist-info/METADATA +229 -0
  45. {janito-3.3.0.dist-info → janito-3.5.0.dist-info}/RECORD +98 -162
  46. janito/plugins/__main__.py +0 -85
  47. janito/plugins/base.py +0 -57
  48. janito/plugins/core_loader.py +0 -144
  49. janito/plugins_backup_20250825_070018/__init__.py +0 -36
  50. janito/plugins_backup_20250825_070018/builtin.py +0 -102
  51. janito/plugins_backup_20250825_070018/config.py +0 -84
  52. janito/plugins_backup_20250825_070018/core/__init__.py +0 -7
  53. janito/plugins_backup_20250825_070018/core/codeanalyzer/__init__.py +0 -43
  54. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/__init__.py +0 -1
  55. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/core.py +0 -122
  56. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/__init__.py +0 -1
  57. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/core.py +0 -205
  58. janito/plugins_backup_20250825_070018/core/filemanager/__init__.py +0 -124
  59. janito/plugins_backup_20250825_070018/core/filemanager/tools/copy_file.py +0 -87
  60. janito/plugins_backup_20250825_070018/core/filemanager/tools/create_directory.py +0 -70
  61. janito/plugins_backup_20250825_070018/core/filemanager/tools/create_file.py +0 -87
  62. janito/plugins_backup_20250825_070018/core/filemanager/tools/delete_text_in_file.py +0 -135
  63. janito/plugins_backup_20250825_070018/core/filemanager/tools/find_files.py +0 -143
  64. janito/plugins_backup_20250825_070018/core/filemanager/tools/move_file.py +0 -131
  65. janito/plugins_backup_20250825_070018/core/filemanager/tools/read_files.py +0 -58
  66. janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_directory.py +0 -55
  67. janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_file.py +0 -58
  68. janito/plugins_backup_20250825_070018/core/filemanager/tools/replace_text_in_file.py +0 -270
  69. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/__init__.py +0 -1
  70. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/core.py +0 -114
  71. janito/plugins_backup_20250825_070018/core/filemanager/tools/view_file.py +0 -172
  72. janito/plugins_backup_20250825_070018/core/imagedisplay/__init__.py +0 -14
  73. janito/plugins_backup_20250825_070018/core/imagedisplay/plugin.py +0 -51
  74. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/__init__.py +0 -1
  75. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image.py +0 -83
  76. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image_grid.py +0 -84
  77. janito/plugins_backup_20250825_070018/core/system/__init__.py +0 -23
  78. janito/plugins_backup_20250825_070018/core/system/tools/run_bash_command.py +0 -183
  79. janito/plugins_backup_20250825_070018/core/system/tools/run_powershell_command.py +0 -218
  80. janito/plugins_backup_20250825_070018/core_adapter.py +0 -55
  81. janito/plugins_backup_20250825_070018/dev/__init__.py +0 -7
  82. janito/plugins_backup_20250825_070018/dev/pythondev/__init__.py +0 -37
  83. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_code_run.py +0 -172
  84. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_command_run.py +0 -171
  85. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_file_run.py +0 -172
  86. janito/plugins_backup_20250825_070018/dev/visualization/__init__.py +0 -23
  87. janito/plugins_backup_20250825_070018/dev/visualization/tools/read_chart.py +0 -259
  88. janito/plugins_backup_20250825_070018/discovery.py +0 -289
  89. janito/plugins_backup_20250825_070018/example_plugin.py +0 -108
  90. janito/plugins_backup_20250825_070018/manager.py +0 -243
  91. janito/plugins_backup_20250825_070018/tools/get_file_outline/java_outline.py +0 -47
  92. janito/plugins_backup_20250825_070018/tools/get_file_outline/markdown_outline.py +0 -14
  93. janito/plugins_backup_20250825_070018/tools/get_file_outline/python_outline.py +0 -303
  94. janito/plugins_backup_20250825_070018/tools/get_file_outline/search_outline.py +0 -36
  95. janito/plugins_backup_20250825_070018/tools/search_text/match_lines.py +0 -67
  96. janito/plugins_backup_20250825_070018/tools/search_text/pattern_utils.py +0 -73
  97. janito/plugins_backup_20250825_070018/tools/search_text/traverse_directory.py +0 -145
  98. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/css_validator.py +0 -35
  99. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/html_validator.py +0 -100
  100. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/jinja2_validator.py +0 -50
  101. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/js_validator.py +0 -27
  102. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/json_validator.py +0 -6
  103. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/markdown_validator.py +0 -109
  104. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/ps1_validator.py +0 -32
  105. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/python_validator.py +0 -5
  106. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/xml_validator.py +0 -11
  107. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/yaml_validator.py +0 -6
  108. janito/plugins_backup_20250825_070018/ui/__init__.py +0 -7
  109. janito/plugins_backup_20250825_070018/ui/userinterface/__init__.py +0 -16
  110. janito/plugins_backup_20250825_070018/ui/userinterface/tools/ask_user.py +0 -110
  111. janito/plugins_backup_20250825_070018/web/__init__.py +0 -7
  112. janito/plugins_backup_20250825_070018/web/webtools/__init__.py +0 -33
  113. janito/plugins_backup_20250825_070018/web/webtools/tools/fetch_url.py +0 -458
  114. janito/plugins_backup_20250825_070018/web/webtools/tools/open_html_in_browser.py +0 -51
  115. janito/plugins_backup_20250825_070018/web/webtools/tools/open_url.py +0 -37
  116. janito/tools/function_adapter.py +0 -176
  117. janito-3.3.0.dist-info/METADATA +0 -83
  118. /janito/{plugin_system_backup_20250825_070018 → plugin_system}/__init__.py +0 -0
  119. /janito/{plugin_system_backup_20250825_070018 → plugin_system}/base.py +0 -0
  120. /janito/{plugins_backup_20250825_070018 → plugins}/auto_loader_fixed.py +0 -0
  121. /janito/{plugins_backup_20250825_070018 → plugins}/tools/__init__.py +0 -0
  122. /janito/{plugins_backup_20250825_070018 → plugins}/tools/ask_user.py +0 -0
  123. /janito/{plugins_backup_20250825_070018 → plugins}/tools/copy_file.py +0 -0
  124. /janito/{plugins_backup_20250825_070018 → plugins}/tools/create_directory.py +0 -0
  125. /janito/{plugins_backup_20250825_070018 → plugins}/tools/decorators.py +0 -0
  126. /janito/{plugins_backup_20250825_070018 → plugins}/tools/fetch_url.py +0 -0
  127. /janito/{plugins_backup_20250825_070018 → plugins}/tools/find_files.py +0 -0
  128. /janito/{plugins_backup_20250825_070018 → plugins}/tools/get_file_outline/__init__.py +0 -0
  129. /janito/{plugins_backup_20250825_070018 → plugins}/tools/get_file_outline/core.py +0 -0
  130. /janito/{plugins_backup_20250825_070018/core/codeanalyzer → plugins}/tools/get_file_outline/java_outline.py +0 -0
  131. /janito/{plugins_backup_20250825_070018/core/codeanalyzer → plugins}/tools/get_file_outline/markdown_outline.py +0 -0
  132. /janito/{plugins_backup_20250825_070018/core/codeanalyzer → plugins}/tools/get_file_outline/python_outline.py +0 -0
  133. /janito/{plugins_backup_20250825_070018/core/codeanalyzer → plugins}/tools/get_file_outline/search_outline.py +0 -0
  134. /janito/{plugins_backup_20250825_070018 → plugins}/tools/move_file.py +0 -0
  135. /janito/{plugins_backup_20250825_070018 → plugins}/tools/open_html_in_browser.py +0 -0
  136. /janito/{plugins_backup_20250825_070018 → plugins}/tools/open_url.py +0 -0
  137. /janito/{plugins_backup_20250825_070018 → plugins}/tools/python_code_run.py +0 -0
  138. /janito/{plugins_backup_20250825_070018 → plugins}/tools/python_command_run.py +0 -0
  139. /janito/{plugins_backup_20250825_070018 → plugins}/tools/python_file_run.py +0 -0
  140. /janito/{plugins_backup_20250825_070018 → plugins}/tools/read_chart.py +0 -0
  141. /janito/{plugins_backup_20250825_070018 → plugins}/tools/read_files.py +0 -0
  142. /janito/{plugins_backup_20250825_070018 → plugins}/tools/remove_directory.py +0 -0
  143. /janito/{plugins_backup_20250825_070018 → plugins}/tools/remove_file.py +0 -0
  144. /janito/{plugins_backup_20250825_070018 → plugins}/tools/replace_text_in_file.py +0 -0
  145. /janito/{plugins_backup_20250825_070018 → plugins}/tools/run_bash_command.py +0 -0
  146. /janito/{plugins_backup_20250825_070018 → plugins}/tools/run_powershell_command.py +0 -0
  147. /janito/{plugins_backup_20250825_070018 → plugins}/tools/search_text/__init__.py +0 -0
  148. /janito/{plugins_backup_20250825_070018 → plugins}/tools/search_text/core.py +0 -0
  149. /janito/{plugins_backup_20250825_070018/core/codeanalyzer → plugins}/tools/search_text/match_lines.py +0 -0
  150. /janito/{plugins_backup_20250825_070018/core/codeanalyzer → plugins}/tools/search_text/pattern_utils.py +0 -0
  151. /janito/{plugins_backup_20250825_070018/core/codeanalyzer → plugins}/tools/search_text/traverse_directory.py +0 -0
  152. /janito/{plugins_backup_20250825_070018 → plugins}/tools/show_image.py +0 -0
  153. /janito/{plugins_backup_20250825_070018 → plugins}/tools/show_image_grid.py +0 -0
  154. /janito/{plugins_backup_20250825_070018 → plugins}/tools/validate_file_syntax/__init__.py +0 -0
  155. /janito/{plugins_backup_20250825_070018 → plugins}/tools/validate_file_syntax/core.py +0 -0
  156. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/css_validator.py +0 -0
  157. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/html_validator.py +0 -0
  158. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/jinja2_validator.py +0 -0
  159. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/js_validator.py +0 -0
  160. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/json_validator.py +0 -0
  161. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/markdown_validator.py +0 -0
  162. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/ps1_validator.py +0 -0
  163. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/python_validator.py +0 -0
  164. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/xml_validator.py +0 -0
  165. /janito/{plugins_backup_20250825_070018/core/filemanager → plugins}/tools/validate_file_syntax/yaml_validator.py +0 -0
  166. /janito/{plugins_backup_20250825_070018 → plugins}/tools/view_file.py +0 -0
  167. {janito-3.3.0.dist-info → janito-3.5.0.dist-info}/WHEEL +0 -0
  168. {janito-3.3.0.dist-info → janito-3.5.0.dist-info}/entry_points.txt +0 -0
  169. {janito-3.3.0.dist-info → janito-3.5.0.dist-info}/licenses/LICENSE +0 -0
  170. {janito-3.3.0.dist-info → janito-3.5.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,107 @@
1
+ """
2
+ Enter key cancellation for LLM requests.
3
+ Allows pressing Enter to cancel ongoing requests.
4
+ """
5
+
6
+ import threading
7
+ import sys
8
+ import time
9
+ from typing import Optional
10
+
11
+
12
+ class EnterCancellation:
13
+ """Handles Enter key cancellation of LLM requests."""
14
+
15
+ def __init__(self):
16
+ self._cancel_event: Optional[threading.Event] = None
17
+ self._listener_thread: Optional[threading.Thread] = None
18
+ self._listening = False
19
+
20
+ def start_monitoring(self, cancel_event: threading.Event):
21
+ """Start monitoring for Enter key to cancel the request."""
22
+ if self._listening:
23
+ return
24
+
25
+ self._cancel_event = cancel_event
26
+ self._listening = True
27
+
28
+ self._listener_thread = threading.Thread(
29
+ target=self._monitor_enter_key, daemon=True
30
+ )
31
+ self._listener_thread.start()
32
+
33
+ def stop_monitoring(self):
34
+ """Stop monitoring for keyboard input."""
35
+ self._listening = False
36
+ if self._listener_thread and self._listener_thread.is_alive():
37
+ self._listener_thread.join(timeout=0.1)
38
+
39
+ def _monitor_enter_key(self):
40
+ """Monitor for Enter key press."""
41
+ try:
42
+ self._handle_key_monitoring()
43
+ except Exception:
44
+ # Silently handle any errors
45
+ pass
46
+
47
+ def _handle_key_monitoring(self):
48
+ """Handle the actual key monitoring logic."""
49
+ import sys
50
+ import select
51
+
52
+ try:
53
+ import msvcrt # Windows-specific keyboard input
54
+
55
+ self._monitor_windows_keys()
56
+ except ImportError:
57
+ self._monitor_unix_keys()
58
+
59
+ def _monitor_windows_keys(self):
60
+ """Monitor keys on Windows systems."""
61
+ import msvcrt
62
+
63
+ while (
64
+ self._listening and self._cancel_event and not self._cancel_event.is_set()
65
+ ):
66
+ try:
67
+ if msvcrt.kbhit():
68
+ char = msvcrt.getch()
69
+ if char in [b"\r", b"\n"]:
70
+ if self._cancel_event:
71
+ self._cancel_event.set()
72
+ break
73
+ else:
74
+ time.sleep(0.05)
75
+ except (IOError, OSError):
76
+ break
77
+
78
+ def _monitor_unix_keys(self):
79
+ """Monitor keys on Unix-like systems."""
80
+ import sys
81
+ import select
82
+
83
+ while (
84
+ self._listening and self._cancel_event and not self._cancel_event.is_set()
85
+ ):
86
+ try:
87
+ if sys.stdin in select.select([sys.stdin], [], [], 0.05)[0]:
88
+ char = sys.stdin.read(1)
89
+ if char in ["\r", "\n"]:
90
+ if self._cancel_event:
91
+ self._cancel_event.set()
92
+ break
93
+ time.sleep(0.05)
94
+ except:
95
+ time.sleep(0.05)
96
+
97
+
98
+ # Global instance
99
+ _global_enter_cancellation = None
100
+
101
+
102
+ def get_enter_cancellation() -> EnterCancellation:
103
+ """Get the global Enter cancellation instance."""
104
+ global _global_enter_cancellation
105
+ if _global_enter_cancellation is None:
106
+ _global_enter_cancellation = EnterCancellation()
107
+ return _global_enter_cancellation
@@ -12,8 +12,7 @@ from pathlib import Path
12
12
  from typing import Optional, List, Type
13
13
 
14
14
  from janito.plugin_system.base import Plugin, PluginMetadata
15
- from janito.tools.function_adapter import create_function_tool
16
- from janito.tools.tool_base import ToolBase
15
+ from janito.tools.tool_base import ToolBase, ToolPermissions
17
16
 
18
17
 
19
18
  class CorePlugin(Plugin):
@@ -38,12 +37,86 @@ class CorePlugin(Plugin):
38
37
  def get_tools(self) -> List[Type[ToolBase]]:
39
38
  return self._tool_classes
40
39
 
40
+ def _create_tool_class(self, func):
41
+ """Create a ToolBase class from a function."""
42
+ resolved_tool_name = getattr(func, "tool_name", func.__name__)
43
+
44
+ # Create a proper tool class with explicit parameters and documentation
45
+ import inspect
46
+ from typing import get_type_hints
47
+
48
+ func_sig = inspect.signature(func)
49
+ type_hints = get_type_hints(func)
50
+
51
+ # Build parameter definitions for the run method
52
+ param_defs = []
53
+ param_docs = []
54
+ for name, param in func_sig.parameters.items():
55
+ type_hint = type_hints.get(name, str)
56
+ if param.default == inspect.Parameter.empty:
57
+ param_defs.append(f"{name}: {type_hint.__name__}")
58
+ else:
59
+ param_defs.append(f"{name}: {type_hint.__name__} = {repr(param.default)}")
60
+
61
+ # Add parameter documentation
62
+ param_docs.append(f" {name}: {type_hint.__name__} - Parameter {name}")
63
+
64
+ # Get function docstring or create one
65
+ func_doc = func.__doc__ or f"Execute {resolved_tool_name} tool"
66
+
67
+ # Create the tool class with proper signature and documentation
68
+ exec_globals = {
69
+ 'ToolBase': ToolBase,
70
+ 'ToolPermissions': ToolPermissions,
71
+ 'func': func,
72
+ 'inspect': inspect,
73
+ 'str': str,
74
+ }
75
+
76
+ param_docs_str = '\n'.join(param_docs)
77
+
78
+ class_def = f'''
79
+ class DynamicTool(ToolBase):
80
+ """
81
+ {func_doc}
82
+
83
+ Parameters:
84
+ {param_docs_str}
85
+
86
+ Returns:
87
+ str: Execution result
88
+ """
89
+ tool_name = "{resolved_tool_name}"
90
+ permissions = ToolPermissions(read=True, write=True, execute=True)
91
+
92
+ def __init__(self):
93
+ super().__init__()
94
+
95
+ def run(self, {', '.join(param_defs)}) -> str:
96
+ kwargs = locals()
97
+ sig = inspect.signature(func)
98
+
99
+ # Filter kwargs to only include parameters the function accepts
100
+ filtered_kwargs = {{}}
101
+ for name, param in sig.parameters.items():
102
+ if name in kwargs and kwargs[name] is not None:
103
+ filtered_kwargs[name] = kwargs[name]
104
+
105
+ result = func(**filtered_kwargs)
106
+ return str(result) if result is not None else ""
107
+ '''
108
+
109
+ exec(class_def, exec_globals)
110
+ return exec_globals['DynamicTool']
111
+
112
+ return DynamicTool
113
+
41
114
  def initialize(self):
42
115
  """Initialize by creating tool classes."""
43
116
  self._tool_classes = []
44
117
  for tool_func in self._tools:
45
118
  if callable(tool_func):
46
- tool_class = create_function_tool(tool_func)
119
+ tool_class = self._create_tool_class(tool_func)
47
120
  self._tool_classes.append(tool_class)
48
121
 
49
122
 
@@ -11,8 +11,7 @@ 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.function_adapter import create_function_tool
15
- from janito.tools.tool_base import ToolBase
14
+ from janito.tools.tool_base import ToolBase, ToolPermissions
16
15
 
17
16
 
18
17
  class CorePlugin(Plugin):
@@ -37,12 +36,89 @@ class CorePlugin(Plugin):
37
36
  def get_tools(self) -> List[Type[ToolBase]]:
38
37
  return self._tool_classes
39
38
 
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
+
40
116
  def initialize(self):
41
117
  """Initialize by creating tool classes."""
42
118
  self._tool_classes = []
43
119
  for tool_func in self._tools:
44
120
  if callable(tool_func):
45
- tool_class = create_function_tool(tool_func)
121
+ tool_class = self._create_tool_class(tool_func)
46
122
  self._tool_classes.append(tool_class)
47
123
 
48
124
 
@@ -1,28 +1,36 @@
1
1
  """
2
- Unified Plugin System for Janito
2
+ Plugin System for Development Tools
3
3
 
4
- This package provides a clean, unified plugin architecture for janito.
4
+ This package organizes all available tools into logical plugin groups
5
+ for easier discovery and usage.
5
6
  """
6
7
 
7
8
  __version__ = "1.0.0"
8
9
  __author__ = "Development Assistant"
9
10
 
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
- ]
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)
@@ -13,7 +13,7 @@ from janito.plugins.discovery import list_available_plugins
13
13
  # List of core plugins that should be enabled by default
14
14
  CORE_PLUGINS = [
15
15
  "core.filemanager",
16
- "core.codeanalyzer",
16
+ "core.codeanalyzer",
17
17
  "core.system",
18
18
  "core.imagedisplay",
19
19
  "dev.pythondev",
@@ -26,23 +26,23 @@ CORE_PLUGINS = [
26
26
  def load_core_plugins(pm: PluginManager = None) -> List[str]:
27
27
  """
28
28
  Load all core plugins.
29
-
29
+
30
30
  Args:
31
31
  pm: PluginManager instance. If None, creates a new one.
32
-
32
+
33
33
  Returns:
34
34
  List of successfully loaded plugin names
35
35
  """
36
36
  if pm is None:
37
37
  pm = PluginManager()
38
-
38
+
39
39
  # Ensure plugins directory is in search path
40
40
  plugins_dir = Path.cwd() / "plugins"
41
41
  if plugins_dir.exists():
42
42
  pm.add_plugin_path(str(plugins_dir))
43
-
43
+
44
44
  loaded = []
45
-
45
+
46
46
  # Load core plugins
47
47
  for plugin_name in CORE_PLUGINS:
48
48
  try:
@@ -50,14 +50,14 @@ def load_core_plugins(pm: PluginManager = None) -> List[str]:
50
50
  loaded.append(plugin_name)
51
51
  except Exception as e:
52
52
  print(f"Warning: Failed to load core plugin {plugin_name}: {e}")
53
-
53
+
54
54
  return loaded
55
55
 
56
56
 
57
57
  def get_loaded_core_plugins() -> List[str]:
58
58
  """
59
59
  Get list of currently loaded core plugins.
60
-
60
+
61
61
  Returns:
62
62
  List of loaded core plugin names
63
63
  """
@@ -69,10 +69,10 @@ def get_loaded_core_plugins() -> List[str]:
69
69
  def is_core_plugin(plugin_name: str) -> bool:
70
70
  """
71
71
  Check if a plugin is a core plugin.
72
-
72
+
73
73
  Args:
74
74
  plugin_name: Name of the plugin to check
75
-
75
+
76
76
  Returns:
77
77
  True if it's a core plugin
78
78
  """
@@ -82,10 +82,11 @@ def is_core_plugin(plugin_name: str) -> bool:
82
82
  # Auto-load core plugins when module is imported
83
83
  _plugin_manager = None
84
84
 
85
+
85
86
  def get_plugin_manager() -> PluginManager:
86
87
  """Get the global plugin manager with core plugins loaded."""
87
88
  global _plugin_manager
88
89
  if _plugin_manager is None:
89
90
  _plugin_manager = PluginManager()
90
91
  load_core_plugins(_plugin_manager)
91
- return _plugin_manager
92
+ return _plugin_manager
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 .base import Plugin
10
+ from janito.plugin_system.base import Plugin
11
11
 
12
12
 
13
13
  class BuiltinPluginRegistry:
@@ -13,36 +13,12 @@ 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
-
17
- Parameters:
16
+ Args:
18
17
  sources (str): Space-separated path(s) to the file(s) to copy.
19
18
  For multiple sources, provide a single string with paths separated by spaces.
20
19
  target (str): Destination path. If copying multiple sources, this must be an existing directory.
21
20
  overwrite (bool, optional): Overwrite existing files. Default: False.
22
21
  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
-
46
22
  Returns:
47
23
  str: Status string for each copy operation.
48
24
  """
@@ -12,35 +12,8 @@ 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
-
16
- Parameters:
15
+ Args:
17
16
  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
-
44
17
  Returns:
45
18
  str: Status message indicating the result. Example:
46
19
  - "5c5 Successfully created the directory at ..."
@@ -16,34 +16,10 @@ class CreateFileTool(ToolBase):
16
16
  """
17
17
  Create a new file with the given content.
18
18
 
19
- Parameters:
19
+ Args:
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
-
47
23
  Returns:
48
24
  str: Status message indicating the result. Example:
49
25
  - "✅ Successfully created the file at ..."
@@ -51,13 +27,13 @@ class CreateFileTool(ToolBase):
51
27
  Note: Syntax validation is automatically performed after this operation.
52
28
 
53
29
  Security: This tool includes loop protection to prevent excessive file creation operations.
54
- Maximum 5 calls per 10 seconds for the same file path.
30
+ Protection: Prevents repeated create calls for the same file path within a short window (1 allowed per 10 seconds).
55
31
  """
56
32
 
57
33
  permissions = ToolPermissions(write=True)
58
34
  tool_name = "create_file"
59
35
 
60
- @protect_against_loops(max_calls=5, time_window=10.0, key_field="path")
36
+ @protect_against_loops(max_calls=1, time_window=10.0, key_field="path")
61
37
  def run(self, path: str, content: str, overwrite: bool = False) -> str:
62
38
  path = expand_path(path)
63
39
  disp_path = display_path(path)
@@ -15,7 +15,6 @@ 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.
19
18
 
20
19
  Returns:
21
20
  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 ...base import Plugin, PluginMetadata
7
+ from janito.plugin_system.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