janito 3.3.0__py3-none-any.whl → 3.4.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 (214) hide show
  1. janito/cli/cli_commands/list_plugins.py +48 -52
  2. janito/cli/core/getters.py +0 -3
  3. janito/cli/main_cli.py +12 -9
  4. janito/drivers/openai/driver.py +0 -1
  5. janito/drivers/zai/driver.py +0 -1
  6. janito/hello.txt +0 -0
  7. janito/llm/auth_utils.py +5 -14
  8. janito/plugins/__init__.py +7 -18
  9. janito/{plugins_backup_20250825_070018 → plugins}/auto_loader_fixed.py +11 -12
  10. janito/plugins/base.py +152 -57
  11. janito/plugins/builtin.py +1 -15
  12. janito/{plugins_backup_20250825_070018 → plugins}/core_adapter.py +9 -11
  13. janito/plugins/core_loader.py +34 -58
  14. janito/{plugin_system_backup_20250825_070018/core_loader.py → plugins/core_loader_fixed.py} +26 -45
  15. janito/plugins/discovery.py +3 -3
  16. janito/tools/__init__.py +7 -31
  17. janito/tools/adapters/__init__.py +1 -6
  18. janito/tools/adapters/local/__init__.py +70 -7
  19. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/ask_user.py +3 -3
  20. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/create_file.py +4 -4
  21. janito/{plugins/core/filemanager/tools → tools/adapters/local}/delete_text_in_file.py +0 -1
  22. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/fetch_url.py +3 -3
  23. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/replace_text_in_file.py +4 -4
  24. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/show_image.py +6 -15
  25. janito/{plugins/core/imagedisplay/tools → tools/adapters/local}/show_image_grid.py +5 -13
  26. janito/tools/base.py +1 -31
  27. janito/tools/function_adapter.py +16 -127
  28. janito/tools/tool_base.py +114 -142
  29. janito/tools/tools_schema.py +6 -12
  30. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/METADATA +2 -1
  31. janito-3.4.0.dist-info/RECORD +264 -0
  32. janito/cli/cli_commands/check_tools.py +0 -212
  33. janito/plugin_system_backup_20250825_070018/__init__.py +0 -10
  34. janito/plugin_system_backup_20250825_070018/base.py +0 -155
  35. janito/plugin_system_backup_20250825_070018/core_loader_fixed.py +0 -149
  36. janito/plugins/__main__.py +0 -85
  37. janito/plugins/core/__init__.py +0 -7
  38. janito/plugins/core/codeanalyzer/__init__.py +0 -43
  39. janito/plugins/core/filemanager/__init__.py +0 -124
  40. janito/plugins/core/filemanager/tools/copy_file.py +0 -111
  41. janito/plugins/core/filemanager/tools/create_directory.py +0 -97
  42. janito/plugins/core/filemanager/tools/create_file.py +0 -111
  43. janito/plugins/core/filemanager/tools/replace_text_in_file.py +0 -270
  44. janito/plugins/core/imagedisplay/__init__.py +0 -14
  45. janito/plugins/core/imagedisplay/plugin.py +0 -51
  46. janito/plugins/core/imagedisplay/tools/__init__.py +0 -1
  47. janito/plugins/core/imagedisplay/tools/show_image.py +0 -83
  48. janito/plugins/core/system/__init__.py +0 -23
  49. janito/plugins/dev/__init__.py +0 -7
  50. janito/plugins/dev/pythondev/__init__.py +0 -37
  51. janito/plugins/dev/visualization/__init__.py +0 -23
  52. janito/plugins/example_plugin.py +0 -108
  53. janito/plugins/ui/__init__.py +0 -7
  54. janito/plugins/ui/userinterface/__init__.py +0 -16
  55. janito/plugins/ui/userinterface/tools/ask_user.py +0 -110
  56. janito/plugins/web/__init__.py +0 -7
  57. janito/plugins/web/webtools/__init__.py +0 -33
  58. janito/plugins/web/webtools/tools/fetch_url.py +0 -458
  59. janito/plugins_backup_20250825_070018/__init__.py +0 -36
  60. janito/plugins_backup_20250825_070018/builtin.py +0 -102
  61. janito/plugins_backup_20250825_070018/config.py +0 -84
  62. janito/plugins_backup_20250825_070018/core/__init__.py +0 -7
  63. janito/plugins_backup_20250825_070018/core/codeanalyzer/__init__.py +0 -43
  64. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/__init__.py +0 -1
  65. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/core.py +0 -122
  66. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/java_outline.py +0 -47
  67. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/markdown_outline.py +0 -14
  68. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/python_outline.py +0 -303
  69. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/search_outline.py +0 -36
  70. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/__init__.py +0 -1
  71. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/core.py +0 -205
  72. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/match_lines.py +0 -67
  73. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/pattern_utils.py +0 -73
  74. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/traverse_directory.py +0 -145
  75. janito/plugins_backup_20250825_070018/core/filemanager/__init__.py +0 -124
  76. janito/plugins_backup_20250825_070018/core/filemanager/tools/create_file.py +0 -87
  77. janito/plugins_backup_20250825_070018/core/filemanager/tools/delete_text_in_file.py +0 -135
  78. janito/plugins_backup_20250825_070018/core/filemanager/tools/find_files.py +0 -143
  79. janito/plugins_backup_20250825_070018/core/filemanager/tools/move_file.py +0 -131
  80. janito/plugins_backup_20250825_070018/core/filemanager/tools/read_files.py +0 -58
  81. janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_directory.py +0 -55
  82. janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_file.py +0 -58
  83. janito/plugins_backup_20250825_070018/core/filemanager/tools/replace_text_in_file.py +0 -270
  84. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/__init__.py +0 -1
  85. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/core.py +0 -114
  86. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/css_validator.py +0 -35
  87. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/html_validator.py +0 -100
  88. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/jinja2_validator.py +0 -50
  89. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/js_validator.py +0 -27
  90. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/json_validator.py +0 -6
  91. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/markdown_validator.py +0 -109
  92. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/ps1_validator.py +0 -32
  93. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/python_validator.py +0 -5
  94. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/xml_validator.py +0 -11
  95. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/yaml_validator.py +0 -6
  96. janito/plugins_backup_20250825_070018/core/filemanager/tools/view_file.py +0 -172
  97. janito/plugins_backup_20250825_070018/core/imagedisplay/__init__.py +0 -14
  98. janito/plugins_backup_20250825_070018/core/imagedisplay/plugin.py +0 -51
  99. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/__init__.py +0 -1
  100. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image.py +0 -83
  101. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image_grid.py +0 -84
  102. janito/plugins_backup_20250825_070018/core/system/__init__.py +0 -23
  103. janito/plugins_backup_20250825_070018/core/system/tools/run_bash_command.py +0 -183
  104. janito/plugins_backup_20250825_070018/core/system/tools/run_powershell_command.py +0 -218
  105. janito/plugins_backup_20250825_070018/dev/__init__.py +0 -7
  106. janito/plugins_backup_20250825_070018/dev/pythondev/__init__.py +0 -37
  107. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_code_run.py +0 -172
  108. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_command_run.py +0 -171
  109. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_file_run.py +0 -172
  110. janito/plugins_backup_20250825_070018/dev/visualization/__init__.py +0 -23
  111. janito/plugins_backup_20250825_070018/dev/visualization/tools/read_chart.py +0 -259
  112. janito/plugins_backup_20250825_070018/discovery.py +0 -289
  113. janito/plugins_backup_20250825_070018/example_plugin.py +0 -108
  114. janito/plugins_backup_20250825_070018/manager.py +0 -243
  115. janito/plugins_backup_20250825_070018/tools/__init__.py +0 -10
  116. janito/plugins_backup_20250825_070018/tools/copy_file.py +0 -87
  117. janito/plugins_backup_20250825_070018/tools/core_tools_plugin.py +0 -88
  118. janito/plugins_backup_20250825_070018/tools/create_directory.py +0 -70
  119. janito/plugins_backup_20250825_070018/tools/decorators.py +0 -19
  120. janito/plugins_backup_20250825_070018/tools/delete_text_in_file.py +0 -135
  121. janito/plugins_backup_20250825_070018/tools/find_files.py +0 -143
  122. janito/plugins_backup_20250825_070018/tools/get_file_outline/__init__.py +0 -7
  123. janito/plugins_backup_20250825_070018/tools/get_file_outline/core.py +0 -122
  124. janito/plugins_backup_20250825_070018/tools/get_file_outline/java_outline.py +0 -47
  125. janito/plugins_backup_20250825_070018/tools/get_file_outline/markdown_outline.py +0 -14
  126. janito/plugins_backup_20250825_070018/tools/get_file_outline/python_outline.py +0 -303
  127. janito/plugins_backup_20250825_070018/tools/get_file_outline/search_outline.py +0 -36
  128. janito/plugins_backup_20250825_070018/tools/move_file.py +0 -131
  129. janito/plugins_backup_20250825_070018/tools/open_html_in_browser.py +0 -51
  130. janito/plugins_backup_20250825_070018/tools/open_url.py +0 -37
  131. janito/plugins_backup_20250825_070018/tools/python_code_run.py +0 -172
  132. janito/plugins_backup_20250825_070018/tools/python_command_run.py +0 -171
  133. janito/plugins_backup_20250825_070018/tools/python_file_run.py +0 -172
  134. janito/plugins_backup_20250825_070018/tools/read_chart.py +0 -259
  135. janito/plugins_backup_20250825_070018/tools/read_files.py +0 -58
  136. janito/plugins_backup_20250825_070018/tools/remove_directory.py +0 -55
  137. janito/plugins_backup_20250825_070018/tools/remove_file.py +0 -58
  138. janito/plugins_backup_20250825_070018/tools/run_bash_command.py +0 -183
  139. janito/plugins_backup_20250825_070018/tools/run_powershell_command.py +0 -218
  140. janito/plugins_backup_20250825_070018/tools/search_text/__init__.py +0 -7
  141. janito/plugins_backup_20250825_070018/tools/search_text/core.py +0 -205
  142. janito/plugins_backup_20250825_070018/tools/search_text/match_lines.py +0 -67
  143. janito/plugins_backup_20250825_070018/tools/search_text/pattern_utils.py +0 -73
  144. janito/plugins_backup_20250825_070018/tools/search_text/traverse_directory.py +0 -145
  145. janito/plugins_backup_20250825_070018/tools/show_image_grid.py +0 -85
  146. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/__init__.py +0 -7
  147. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/core.py +0 -114
  148. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/css_validator.py +0 -35
  149. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/html_validator.py +0 -100
  150. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/jinja2_validator.py +0 -50
  151. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/js_validator.py +0 -27
  152. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/json_validator.py +0 -6
  153. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/markdown_validator.py +0 -109
  154. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/ps1_validator.py +0 -32
  155. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/python_validator.py +0 -5
  156. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/xml_validator.py +0 -11
  157. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/yaml_validator.py +0 -6
  158. janito/plugins_backup_20250825_070018/tools/view_file.py +0 -172
  159. janito/plugins_backup_20250825_070018/ui/__init__.py +0 -7
  160. janito/plugins_backup_20250825_070018/ui/userinterface/__init__.py +0 -16
  161. janito/plugins_backup_20250825_070018/ui/userinterface/tools/ask_user.py +0 -110
  162. janito/plugins_backup_20250825_070018/web/__init__.py +0 -7
  163. janito/plugins_backup_20250825_070018/web/webtools/__init__.py +0 -33
  164. janito/plugins_backup_20250825_070018/web/webtools/tools/fetch_url.py +0 -458
  165. janito/plugins_backup_20250825_070018/web/webtools/tools/open_html_in_browser.py +0 -51
  166. janito/plugins_backup_20250825_070018/web/webtools/tools/open_url.py +0 -37
  167. janito/tools/cli_initializer.py +0 -88
  168. janito/tools/initialize.py +0 -70
  169. janito-3.3.0.dist-info/RECORD +0 -400
  170. /janito/{plugins_backup_20250825_070018 → plugins}/auto_loader.py +0 -0
  171. /janito/{plugins_backup_20250825_070018 → plugins}/discovery_core.py +0 -0
  172. /janito/{plugins_backup_20250825_070018/core/filemanager/tools → tools/adapters/local}/copy_file.py +0 -0
  173. /janito/{plugins_backup_20250825_070018/core/filemanager/tools → tools/adapters/local}/create_directory.py +0 -0
  174. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/find_files.py +0 -0
  175. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/__init__.py +0 -0
  176. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/core.py +0 -0
  177. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/java_outline.py +0 -0
  178. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/markdown_outline.py +0 -0
  179. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/python_outline.py +0 -0
  180. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/search_outline.py +0 -0
  181. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/move_file.py +0 -0
  182. /janito/{plugins/web/webtools/tools → tools/adapters/local}/open_html_in_browser.py +0 -0
  183. /janito/{plugins/web/webtools/tools → tools/adapters/local}/open_url.py +0 -0
  184. /janito/{plugins/dev/pythondev/tools → tools/adapters/local}/python_code_run.py +0 -0
  185. /janito/{plugins/dev/pythondev/tools → tools/adapters/local}/python_command_run.py +0 -0
  186. /janito/{plugins/dev/pythondev/tools → tools/adapters/local}/python_file_run.py +0 -0
  187. /janito/{plugins/dev/visualization/tools → tools/adapters/local}/read_chart.py +0 -0
  188. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/read_files.py +0 -0
  189. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/remove_directory.py +0 -0
  190. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/remove_file.py +0 -0
  191. /janito/{plugins/core/system/tools → tools/adapters/local}/run_bash_command.py +0 -0
  192. /janito/{plugins/core/system/tools → tools/adapters/local}/run_powershell_command.py +0 -0
  193. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/__init__.py +0 -0
  194. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/core.py +0 -0
  195. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/match_lines.py +0 -0
  196. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/pattern_utils.py +0 -0
  197. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/traverse_directory.py +0 -0
  198. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/__init__.py +0 -0
  199. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/core.py +0 -0
  200. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/css_validator.py +0 -0
  201. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/html_validator.py +0 -0
  202. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/jinja2_validator.py +0 -0
  203. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/js_validator.py +0 -0
  204. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/json_validator.py +0 -0
  205. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/markdown_validator.py +0 -0
  206. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/ps1_validator.py +0 -0
  207. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/python_validator.py +0 -0
  208. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/xml_validator.py +0 -0
  209. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/yaml_validator.py +0 -0
  210. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/view_file.py +0 -0
  211. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/WHEEL +0 -0
  212. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/entry_points.txt +0 -0
  213. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/licenses/LICENSE +0 -0
  214. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,12 @@
1
1
  from janito.tools.tool_base import ToolBase, ToolPermissions
2
2
  from janito.report_events import ReportAction
3
- from janito.plugins.tools.decorators import register_core_tool
3
+ from janito.tools.adapters.local.adapter import register_local_tool
4
4
  from janito.i18n import tr
5
5
  from janito.tools.loop_protection_decorator import protect_against_loops
6
6
 
7
7
 
8
- @register_core_tool
9
- class ShowImage(ToolBase):
8
+ @register_local_tool
9
+ class ShowImageTool(ToolBase):
10
10
  """Display an image inline in the terminal using the rich library.
11
11
 
12
12
  Args:
@@ -44,9 +44,7 @@ class ShowImage(ToolBase):
44
44
 
45
45
  path = expand_path(path)
46
46
  disp_path = display_path(path)
47
- self.report_action(
48
- tr("🖼️ Show image '{disp_path}'", disp_path=disp_path), ReportAction.READ
49
- )
47
+ self.report_action(tr("🖼️ Show image '{disp_path}'", disp_path=disp_path), ReportAction.READ)
50
48
 
51
49
  if not os.path.exists(path):
52
50
  msg = tr("❗ not found")
@@ -57,14 +55,9 @@ class ShowImage(ToolBase):
57
55
  console = Console()
58
56
  from rich.console import Console
59
57
  from rich.text import Text
60
-
61
58
  console = Console()
62
59
  img = PILImage.open(path)
63
- console.print(
64
- Text(
65
- f"Image: {disp_path} ({img.width}x{img.height})", style="bold green"
66
- )
67
- )
60
+ console.print(Text(f"Image: {disp_path} ({img.width}x{img.height})", style="bold green"))
68
61
  console.print(img)
69
62
  self.report_success(tr("✅ Displayed"))
70
63
  details = []
@@ -75,9 +68,7 @@ class ShowImage(ToolBase):
75
68
  if not preserve_aspect:
76
69
  details.append("preserve_aspect=False")
77
70
  info = ("; ".join(details)) if details else "auto-fit"
78
- return tr(
79
- "Image displayed: {disp_path} ({info})", disp_path=disp_path, info=info
80
- )
71
+ return tr("Image displayed: {disp_path} ({info})", disp_path=disp_path, info=info)
81
72
  except Exception as e:
82
73
  self.report_error(tr(" ❌ Error: {error}", error=e))
83
74
  return tr("Error displaying image: {error}", error=e)
@@ -1,10 +1,12 @@
1
1
  from janito.tools.tool_base import ToolBase, ToolPermissions
2
2
  from janito.report_events import ReportAction
3
+ from janito.tools.adapters.local.adapter import register_local_tool
3
4
  from janito.i18n import tr
4
5
  from janito.tools.loop_protection_decorator import protect_against_loops
5
6
  from typing import Sequence
6
7
 
7
8
 
9
+ @register_local_tool
8
10
  class ShowImageGridTool(ToolBase):
9
11
  """Display multiple images in a grid inline in the terminal using rich.
10
12
 
@@ -48,9 +50,7 @@ class ShowImageGridTool(ToolBase):
48
50
  if not paths:
49
51
  return tr("No images provided")
50
52
 
51
- self.report_action(
52
- tr("🖼️ Show image grid ({n} images)", n=len(paths)), ReportAction.READ
53
- )
53
+ self.report_action(tr("🖼️ Show image grid ({n} images)", n=len(paths)), ReportAction.READ)
54
54
 
55
55
  console = Console()
56
56
  images = []
@@ -63,9 +63,7 @@ class ShowImageGridTool(ToolBase):
63
63
  try:
64
64
  img = PILImage.open(fp)
65
65
  title = f"{display_path(fp)} ({img.width}x{img.height})"
66
- images.append(
67
- Panel.fit(title, title=display_path(fp), border_style="dim")
68
- )
66
+ images.append(Panel.fit(title, title=display_path(fp), border_style="dim"))
69
67
  shown += 1
70
68
  except Exception as e:
71
69
  self.report_warning(tr("⚠️ Skipped {p}: {e}", p=display_path(fp), e=e))
@@ -73,12 +71,6 @@ class ShowImageGridTool(ToolBase):
73
71
  if not images:
74
72
  return tr("No images could be displayed")
75
73
 
76
- # Render in columns (grid-like)
77
74
  console.print(Columns(images, equal=True, expand=True, columns=columns))
78
75
  self.report_success(tr("✅ Displayed {n} images", n=shown))
79
- return tr(
80
- "Displayed {shown}/{total} images in a {cols}x? grid",
81
- shown=shown,
82
- total=len(paths),
83
- cols=columns,
84
- )
76
+ return tr("Displayed {shown}/{total} images in a {cols}x? grid", shown=shown, total=len(paths), cols=columns)
janito/tools/base.py CHANGED
@@ -1,35 +1,5 @@
1
1
  class BaseTool:
2
- """
3
- Base class for all tools.
4
-
5
- Parameters:
6
- path (str): Target file path for file operations
7
- content (str): File content to write or process
8
- overwrite (bool): Whether to overwrite existing files (default: False)
9
- sources (str): Source file(s) to copy from
10
- target (str): Destination path for copy operations
11
- recursive (bool): Whether to process directories recursively
12
- from_line (int): Starting line number for file reading
13
- to_line (int): Ending line number for file reading
14
- search_text (str): Text to search for in files
15
- replacement_text (str): Text to replace search matches with
16
- use_regex (bool): Whether to treat search as regex pattern
17
- case_sensitive (bool): Whether search should be case sensitive
18
- max_depth (int): Maximum directory depth to search
19
- include_gitignored (bool): Whether to include .gitignored files
20
- timeout (int): Timeout in seconds for operations
21
- require_confirmation (bool): Whether to require user confirmation
22
- data (dict): Chart data for visualization tools
23
- title (str): Chart title
24
- width (int): Chart width in pixels
25
- height (int): Chart height in pixels
26
- query (str): Search query for text search
27
- paths (str): Directory or file paths to search in
28
- src_path (str): Source path for move operations
29
- dest_path (str): Destination path for move operations
30
- code (str): Python code to execute
31
- pattern (str): File pattern to match (e.g., '*.py')
32
- """
2
+ """Base class for all tools."""
33
3
 
34
4
  tool_name: str = ""
35
5
 
@@ -10,167 +10,56 @@ from janito.tools.tool_base import ToolBase, ToolPermissions
10
10
 
11
11
 
12
12
  class FunctionToolAdapter(ToolBase):
13
- """
14
- Adapter that wraps a function into a ToolBase class.
15
-
16
- This adapter provides a unified interface for function-based tools by wrapping
17
- individual functions with the ToolBase protocol. It handles parameter mapping
18
- and validation automatically.
13
+ """Adapter that wraps a function into a ToolBase class."""
19
14
 
20
- Parameters:
21
- path (str): Target file path for file operations
22
- content (str): File content to write or process
23
- overwrite (bool): Whether to overwrite existing files (default: False)
24
- sources (str): Source file(s) to copy from
25
- target (str): Destination path for copy operations
26
- recursive (bool): Whether to process directories recursively
27
- from_line (int): Starting line number for file reading
28
- to_line (int): Ending line number for file reading
29
- search_text (str): Text to search for in files
30
- replacement_text (str): Text to replace search matches with
31
- use_regex (bool): Whether to treat search as regex pattern
32
- case_sensitive (bool): Whether search should be case sensitive
33
- max_depth (int): Maximum directory depth to search
34
- include_gitignored (bool): Whether to include .gitignored files
35
- timeout (int): Timeout in seconds for operations
36
- require_confirmation (bool): Whether to require user confirmation
37
- data (dict): Chart data for visualization tools
38
- title (str): Chart title
39
- width (int): Chart width in pixels
40
- height (int): Chart height in pixels
41
- query (str): Search query for text search
42
- paths (str): Directory or file paths to search in
43
- src_path (str): Source path for move operations
44
- dest_path (str): Destination path for move operations
45
- code (str): Python code to execute
46
- pattern (str): File pattern to match (e.g., '*.py')
47
- """
48
-
49
15
  def __init__(self, func, tool_name: str = None, description: str = None):
50
16
  super().__init__()
51
17
  self._func = func
52
- self.tool_name = tool_name or getattr(func, "tool_name", func.__name__)
18
+ self.tool_name = tool_name or func.__name__
53
19
  self._description = description or func.__doc__ or f"Tool: {self.tool_name}"
54
20
  self.permissions = ToolPermissions(read=True, write=True, execute=True)
55
-
56
- def run(
57
- self,
58
- path: str = None,
59
- content: str = None,
60
- overwrite: bool = None,
61
- sources: str = None,
62
- target: str = None,
63
- recursive: bool = None,
64
- from_line: int = None,
65
- to_line: int = None,
66
- search_text: str = None,
67
- replacement_text: str = None,
68
- use_regex: bool = None,
69
- case_sensitive: bool = None,
70
- max_depth: int = None,
71
- include_gitignored: bool = None,
72
- timeout: int = None,
73
- require_confirmation: bool = None,
74
- data: dict = None,
75
- title: str = None,
76
- width: int = None,
77
- height: int = None,
78
- query: str = None,
79
- paths: str = None,
80
- src_path: str = None,
81
- dest_path: str = None,
82
- code: str = None,
83
- pattern: str = None,
84
- ) -> str:
21
+
22
+ def run(self, **kwargs) -> Any:
85
23
  """Execute the wrapped function."""
86
- # Build kwargs from non-None parameters
87
- import inspect
88
-
89
- sig = inspect.signature(self._func)
90
- filtered_kwargs = {}
91
-
92
- # Map parameter names to their actual values
93
- param_map = {
94
- "path": path,
95
- "content": content,
96
- "overwrite": overwrite,
97
- "sources": sources,
98
- "target": target,
99
- "recursive": recursive,
100
- "from_line": from_line,
101
- "to_line": to_line,
102
- "search_text": search_text,
103
- "replacement_text": replacement_text,
104
- "use_regex": use_regex,
105
- "case_sensitive": case_sensitive,
106
- "max_depth": max_depth,
107
- "include_gitignored": include_gitignored,
108
- "timeout": timeout,
109
- "require_confirmation": require_confirmation,
110
- "data": data,
111
- "title": title,
112
- "width": width,
113
- "height": height,
114
- "query": query,
115
- "paths": paths,
116
- "src_path": src_path,
117
- "dest_path": dest_path,
118
- "code": code,
119
- "pattern": pattern,
120
- }
121
-
122
- # Only include parameters that exist in the function signature
123
- for name, param in sig.parameters.items():
124
- if name in param_map and param_map[name] is not None:
125
- filtered_kwargs[name] = param_map[name]
126
-
127
- result = self._func(**filtered_kwargs)
128
- return str(result) if result is not None else ""
129
-
24
+ return self._func(**kwargs)
25
+
130
26
  def get_signature(self) -> Dict[str, Any]:
131
27
  """Get function signature for documentation."""
132
28
  sig = inspect.signature(self._func)
133
29
  type_hints = get_type_hints(self._func)
134
-
30
+
135
31
  params = {}
136
32
  for name, param in sig.parameters.items():
137
33
  param_info = {
138
34
  "type": str(type_hints.get(name, Any)),
139
- "default": (
140
- param.default if param.default != inspect.Parameter.empty else None
141
- ),
35
+ "default": param.default if param.default != inspect.Parameter.empty else None,
142
36
  "required": param.default == inspect.Parameter.empty,
143
37
  }
144
38
  params[name] = param_info
145
-
39
+
146
40
  return {
147
41
  "name": self.tool_name,
148
42
  "description": self._description,
149
43
  "parameters": params,
150
- "return_type": str(type_hints.get("return", Any)),
44
+ "return_type": str(type_hints.get("return", Any))
151
45
  }
152
46
 
153
47
 
154
48
  def create_function_tool(func, tool_name: str = None, description: str = None) -> type:
155
49
  """
156
50
  Create a ToolBase class from a function.
157
-
51
+
158
52
  Args:
159
53
  func: The function to wrap
160
54
  tool_name: Optional custom tool name
161
55
  description: Optional custom description
162
-
56
+
163
57
  Returns:
164
58
  A ToolBase subclass that wraps the function
165
59
  """
166
- # Resolve tool_name in outer scope
167
- resolved_tool_name = tool_name or getattr(func, "tool_name", func.__name__)
168
-
60
+
169
61
  class DynamicFunctionTool(FunctionToolAdapter):
170
- permissions = ToolPermissions(read=True, write=True, execute=True)
171
- tool_name = resolved_tool_name
172
-
173
62
  def __init__(self):
174
- super().__init__(func, DynamicFunctionTool.tool_name, description)
175
-
176
- return DynamicFunctionTool
63
+ super().__init__(func, tool_name, description)
64
+
65
+ return DynamicFunctionTool
janito/tools/tool_base.py CHANGED
@@ -1,142 +1,114 @@
1
- from janito.report_events import ReportEvent, ReportSubtype, ReportAction
2
- from janito.event_bus.bus import event_bus as default_event_bus
3
-
4
-
5
- from collections import namedtuple
6
-
7
-
8
- class ToolPermissions(namedtuple("ToolPermissions", ["read", "write", "execute"])):
9
- __slots__ = ()
10
-
11
- def __new__(cls, read=False, write=False, execute=False):
12
- return super().__new__(cls, read, write, execute)
13
-
14
- def __repr__(self):
15
- return f"ToolPermissions(read={self.read}, write={self.write}, execute={self.execute})"
16
-
17
-
18
- class ToolBase:
19
- """
20
- Base class for all tools in the janito project.
21
- Extend this class to implement specific tool functionality.
22
-
23
- Parameters:
24
- path (str): Target file path for file operations
25
- content (str): File content to write or process
26
- overwrite (bool): Whether to overwrite existing files (default: False)
27
- sources (str): Source file(s) to copy from
28
- target (str): Destination path for copy operations
29
- recursive (bool): Whether to process directories recursively
30
- from_line (int): Starting line number for file reading
31
- to_line (int): Ending line number for file reading
32
- search_text (str): Text to search for in files
33
- replacement_text (str): Text to replace search matches with
34
- use_regex (bool): Whether to treat search as regex pattern
35
- case_sensitive (bool): Whether search should be case sensitive
36
- max_depth (int): Maximum directory depth to search
37
- include_gitignored (bool): Whether to include .gitignored files
38
- timeout (int): Timeout in seconds for operations
39
- require_confirmation (bool): Whether to require user confirmation
40
- data (dict): Chart data for visualization tools
41
- title (str): Chart title
42
- width (int): Chart width in pixels
43
- height (int): Chart height in pixels
44
- query (str): Search query for text search
45
- paths (str): Directory or file paths to search in
46
- src_path (str): Source path for move operations
47
- dest_path (str): Destination path for move operations
48
- code (str): Python code to execute
49
- pattern (str): File pattern to match (e.g., '*.py')
50
- """
51
-
52
- permissions: "ToolPermissions" = None # Required: must be set by subclasses
53
-
54
- def __init__(self, name=None, event_bus=None):
55
- if self.permissions is None or not isinstance(
56
- self.permissions, ToolPermissions
57
- ):
58
- raise ValueError(
59
- f"Tool '{self.__class__.__name__}' must define a 'permissions' attribute of type ToolPermissions."
60
- )
61
- self.name = name or self.__class__.__name__
62
- self._event_bus = event_bus or default_event_bus
63
-
64
- @property
65
- def event_bus(self):
66
- return self._event_bus
67
-
68
- @event_bus.setter
69
- def event_bus(self, bus):
70
- self._event_bus = bus or default_event_bus
71
-
72
- def report_action(self, message: str, action: ReportAction, context: dict = None):
73
- """
74
- Report that a tool action is starting. This should be the first reporting call for every tool action.
75
- """
76
- self._event_bus.publish(
77
- ReportEvent(
78
- subtype=ReportSubtype.ACTION_INFO,
79
- message=" " + message,
80
- action=action,
81
- tool=self.name,
82
- context=context,
83
- )
84
- )
85
-
86
- def report_error(self, message: str, context: dict = None):
87
- self._event_bus.publish(
88
- ReportEvent(
89
- subtype=ReportSubtype.ERROR,
90
- message=message,
91
- action=None,
92
- tool=self.name,
93
- context=context,
94
- )
95
- )
96
-
97
- def report_success(self, message: str, context: dict = None):
98
- self._event_bus.publish(
99
- ReportEvent(
100
- subtype=ReportSubtype.SUCCESS,
101
- message=message,
102
- action=None,
103
- tool=self.name,
104
- context=context,
105
- )
106
- )
107
-
108
- def report_warning(self, message: str, context: dict = None):
109
- self._event_bus.publish(
110
- ReportEvent(
111
- subtype=ReportSubtype.WARNING,
112
- message=message,
113
- action=None,
114
- tool=self.name,
115
- context=context,
116
- )
117
- )
118
-
119
- def report_stdout(self, message: str, context: dict = None):
120
- self._event_bus.publish(
121
- ReportEvent(
122
- subtype=ReportSubtype.STDOUT,
123
- message=message,
124
- action=None,
125
- tool=self.name,
126
- context=context,
127
- )
128
- )
129
-
130
- def report_stderr(self, message: str, context: dict = None):
131
- self._event_bus.publish(
132
- ReportEvent(
133
- subtype=ReportSubtype.STDERR,
134
- message=message,
135
- action=None,
136
- tool=self.name,
137
- context=context,
138
- )
139
- )
140
-
141
- def run(self, *args, **kwargs):
142
- raise NotImplementedError("Subclasses must implement the run method.")
1
+ from janito.report_events import ReportEvent, ReportSubtype, ReportAction
2
+ from janito.event_bus.bus import event_bus as default_event_bus
3
+
4
+
5
+ from collections import namedtuple
6
+
7
+
8
+ class ToolPermissions(namedtuple("ToolPermissions", ["read", "write", "execute"])):
9
+ __slots__ = ()
10
+
11
+ def __new__(cls, read=False, write=False, execute=False):
12
+ return super().__new__(cls, read, write, execute)
13
+
14
+ def __repr__(self):
15
+ return f"ToolPermissions(read={self.read}, write={self.write}, execute={self.execute})"
16
+
17
+
18
+ class ToolBase:
19
+ """
20
+ Base class for all tools in the janito project.
21
+ Extend this class to implement specific tool functionality.
22
+ """
23
+
24
+ permissions: "ToolPermissions" = None # Required: must be set by subclasses
25
+
26
+ def __init__(self, name=None, event_bus=None):
27
+ if self.permissions is None or not isinstance(
28
+ self.permissions, ToolPermissions
29
+ ):
30
+ raise ValueError(
31
+ f"Tool '{self.__class__.__name__}' must define a 'permissions' attribute of type ToolPermissions."
32
+ )
33
+ self.name = name or self.__class__.__name__
34
+ self._event_bus = event_bus or default_event_bus
35
+
36
+ @property
37
+ def event_bus(self):
38
+ return self._event_bus
39
+
40
+ @event_bus.setter
41
+ def event_bus(self, bus):
42
+ self._event_bus = bus or default_event_bus
43
+
44
+ def report_action(self, message: str, action: ReportAction, context: dict = None):
45
+ """
46
+ Report that a tool action is starting. This should be the first reporting call for every tool action.
47
+ """
48
+ self._event_bus.publish(
49
+ ReportEvent(
50
+ subtype=ReportSubtype.ACTION_INFO,
51
+ message=" " + message,
52
+ action=action,
53
+ tool=self.name,
54
+ context=context,
55
+ )
56
+ )
57
+
58
+ def report_error(self, message: str, context: dict = None):
59
+ self._event_bus.publish(
60
+ ReportEvent(
61
+ subtype=ReportSubtype.ERROR,
62
+ message=message,
63
+ action=None,
64
+ tool=self.name,
65
+ context=context,
66
+ )
67
+ )
68
+
69
+ def report_success(self, message: str, context: dict = None):
70
+ self._event_bus.publish(
71
+ ReportEvent(
72
+ subtype=ReportSubtype.SUCCESS,
73
+ message=message,
74
+ action=None,
75
+ tool=self.name,
76
+ context=context,
77
+ )
78
+ )
79
+
80
+ def report_warning(self, message: str, context: dict = None):
81
+ self._event_bus.publish(
82
+ ReportEvent(
83
+ subtype=ReportSubtype.WARNING,
84
+ message=message,
85
+ action=None,
86
+ tool=self.name,
87
+ context=context,
88
+ )
89
+ )
90
+
91
+ def report_stdout(self, message: str, context: dict = None):
92
+ self._event_bus.publish(
93
+ ReportEvent(
94
+ subtype=ReportSubtype.STDOUT,
95
+ message=message,
96
+ action=None,
97
+ tool=self.name,
98
+ context=context,
99
+ )
100
+ )
101
+
102
+ def report_stderr(self, message: str, context: dict = None):
103
+ self._event_bus.publish(
104
+ ReportEvent(
105
+ subtype=ReportSubtype.STDERR,
106
+ message=message,
107
+ action=None,
108
+ tool=self.name,
109
+ context=context,
110
+ )
111
+ )
112
+
113
+ def run(self, *args, **kwargs):
114
+ raise NotImplementedError("Subclasses must implement the run method.")
@@ -7,8 +7,6 @@ class ToolSchemaBase:
7
7
  def parse_param_section(self, lines, param_section_headers):
8
8
  param_descs = {}
9
9
  in_params = False
10
- current_param = None
11
-
12
10
  for line in lines:
13
11
  stripped_line = line.strip()
14
12
  if any(
@@ -18,21 +16,17 @@ class ToolSchemaBase:
18
16
  in_params = True
19
17
  continue
20
18
  if in_params:
21
- # Check for parameter definition: "param_name (type): description"
22
19
  m = re.match(
23
- r"([a-zA-Z_][a-zA-Z0-9_]*)\s*(?:\([^)]+\))?\s*:\s*(.+)",
20
+ r"([a-zA-Z_][a-zA-Z0-9_]*)\s*(?:\(([^)]+)\))?\s*[:\-]?\s*(.+)",
24
21
  stripped_line,
25
22
  )
26
23
  if m:
27
- param, desc = m.groups()
24
+ param, _, desc = m.groups()
28
25
  param_descs[param] = desc.strip()
29
- current_param = param
30
- elif current_param and stripped_line and not (
31
- stripped_line.lower().startswith("returns:") or
32
- stripped_line.lower() == "returns"
33
- ):
34
- # Continuation of current parameter description
35
- param_descs[current_param] += " " + stripped_line.strip()
26
+ elif stripped_line and stripped_line[0] != "-":
27
+ if param_descs:
28
+ last = list(param_descs)[-1]
29
+ param_descs[last] += " " + stripped_line
36
30
  if (
37
31
  stripped_line.lower().startswith("returns:")
38
32
  or stripped_line.lower() == "returns"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 3.3.0
3
+ Version: 3.4.0
4
4
  Summary: A new Python package called janito.
5
5
  Author-email: João Pinto <janito@ikignosis.org>
6
6
  Project-URL: Homepage, https://github.com/ikignosis/janito
@@ -30,6 +30,7 @@ Requires-Dist: black; extra == "dev"
30
30
  Requires-Dist: questionary>=2.0.1; extra == "dev"
31
31
  Requires-Dist: setuptools_scm>=8.0; extra == "dev"
32
32
  Provides-Extra: coder
33
+ Requires-Dist: janito-coder; extra == "coder"
33
34
  Dynamic: license-file
34
35
 
35
36
  # nctl