janito 2.3.1__py3-none-any.whl → 2.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 (107) hide show
  1. janito/__init__.py +1 -1
  2. janito/_version.py +57 -0
  3. janito/agent/setup_agent.py +95 -21
  4. janito/agent/templates/profiles/system_prompt_template_assistant.txt.j2 +1 -0
  5. janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +44 -0
  6. janito/cli/chat_mode/bindings.py +21 -2
  7. janito/cli/chat_mode/chat_entry.py +2 -3
  8. janito/cli/chat_mode/prompt_style.py +5 -0
  9. janito/cli/chat_mode/script_runner.py +153 -0
  10. janito/cli/chat_mode/session.py +128 -122
  11. janito/cli/chat_mode/session_profile_select.py +80 -0
  12. janito/cli/chat_mode/shell/commands/__init__.py +19 -9
  13. janito/cli/chat_mode/shell/commands/_priv_check.py +5 -0
  14. janito/cli/chat_mode/shell/commands/bang.py +36 -0
  15. janito/cli/chat_mode/shell/commands/conversation_restart.py +31 -24
  16. janito/cli/chat_mode/shell/commands/execute.py +42 -0
  17. janito/cli/chat_mode/shell/commands/help.py +7 -4
  18. janito/cli/chat_mode/shell/commands/model.py +28 -0
  19. janito/cli/chat_mode/shell/commands/prompt.py +0 -8
  20. janito/cli/chat_mode/shell/commands/read.py +37 -0
  21. janito/cli/chat_mode/shell/commands/tools.py +45 -18
  22. janito/cli/chat_mode/shell/commands/write.py +37 -0
  23. janito/cli/chat_mode/shell/commands.bak.zip +0 -0
  24. janito/cli/chat_mode/shell/input_history.py +1 -1
  25. janito/cli/chat_mode/shell/session/manager.py +0 -68
  26. janito/cli/chat_mode/shell/session.bak.zip +0 -0
  27. janito/cli/chat_mode/toolbar.py +44 -27
  28. janito/cli/cli_commands/list_tools.py +44 -11
  29. janito/cli/cli_commands/model_utils.py +95 -95
  30. janito/cli/cli_commands/show_system_prompt.py +57 -14
  31. janito/cli/config.py +5 -6
  32. janito/cli/core/getters.py +33 -33
  33. janito/cli/core/runner.py +27 -20
  34. janito/cli/core/setters.py +10 -1
  35. janito/cli/main_cli.py +40 -10
  36. janito/cli/prompt_core.py +18 -2
  37. janito/cli/prompt_setup.py +56 -0
  38. janito/cli/rich_terminal_reporter.py +21 -6
  39. janito/cli/single_shot_mode/handler.py +24 -77
  40. janito/cli/verbose_output.py +1 -1
  41. janito/config_manager.py +125 -112
  42. janito/drivers/dashscope.bak.zip +0 -0
  43. janito/drivers/driver_registry.py +0 -2
  44. janito/drivers/openai/README.md +20 -0
  45. janito/drivers/openai_responses.bak.zip +0 -0
  46. janito/event_bus/event.py +2 -2
  47. janito/formatting_token.py +7 -6
  48. janito/i18n/pt.py +0 -1
  49. janito/llm/README.md +23 -0
  50. janito/llm/agent.py +80 -16
  51. janito/llm/auth.py +63 -63
  52. janito/llm/driver.py +8 -0
  53. janito/provider_registry.py +178 -176
  54. janito/providers/__init__.py +0 -2
  55. janito/providers/azure_openai/model_info.py +16 -16
  56. janito/providers/dashscope.bak.zip +0 -0
  57. janito/providers/provider_static_info.py +0 -3
  58. janito/providers/registry.py +26 -26
  59. janito/shell.bak.zip +0 -0
  60. janito/tools/DOCSTRING_STANDARD.txt +33 -0
  61. janito/tools/README.md +3 -0
  62. janito/tools/__init__.py +20 -6
  63. janito/tools/adapters/local/__init__.py +65 -62
  64. janito/tools/adapters/local/adapter.py +18 -35
  65. janito/tools/adapters/local/ask_user.py +3 -4
  66. janito/tools/adapters/local/copy_file.py +2 -2
  67. janito/tools/adapters/local/create_directory.py +2 -2
  68. janito/tools/adapters/local/create_file.py +2 -2
  69. janito/tools/adapters/local/delete_text_in_file.py +2 -2
  70. janito/tools/adapters/local/fetch_url.py +2 -2
  71. janito/tools/adapters/local/find_files.py +2 -1
  72. janito/tools/adapters/local/get_file_outline/core.py +2 -2
  73. janito/tools/adapters/local/get_file_outline/search_outline.py +2 -2
  74. janito/tools/adapters/local/move_file.py +2 -2
  75. janito/tools/adapters/local/open_html_in_browser.py +2 -1
  76. janito/tools/adapters/local/open_url.py +2 -2
  77. janito/tools/adapters/local/python_code_run.py +3 -3
  78. janito/tools/adapters/local/python_command_run.py +3 -3
  79. janito/tools/adapters/local/python_file_run.py +3 -3
  80. janito/tools/adapters/local/remove_directory.py +2 -2
  81. janito/tools/adapters/local/remove_file.py +2 -2
  82. janito/tools/adapters/local/replace_text_in_file.py +2 -2
  83. janito/tools/adapters/local/run_bash_command.py +3 -3
  84. janito/tools/adapters/local/run_powershell_command.py +3 -3
  85. janito/tools/adapters/local/search_text/core.py +2 -2
  86. janito/tools/adapters/local/validate_file_syntax/core.py +3 -3
  87. janito/tools/adapters/local/view_file.py +2 -1
  88. janito/tools/outline_file.bak.zip +0 -0
  89. janito/tools/permissions.py +45 -0
  90. janito/tools/permissions_parse.py +12 -0
  91. janito/tools/tool_base.py +14 -11
  92. janito/tools/tool_utils.py +4 -6
  93. janito/tools/tools_adapter.py +25 -20
  94. {janito-2.3.1.dist-info → janito-2.5.0.dist-info}/METADATA +46 -24
  95. {janito-2.3.1.dist-info → janito-2.5.0.dist-info}/RECORD +99 -82
  96. janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +0 -13
  97. janito/agent/templates/profiles/system_prompt_template_main.txt.j2 +0 -37
  98. janito/cli/chat_mode/shell/commands/edit.py +0 -25
  99. janito/cli/chat_mode/shell/commands/exec.py +0 -27
  100. janito/cli/chat_mode/shell/commands/termweb_log.py +0 -92
  101. janito/cli/termweb_starter.py +0 -122
  102. janito/termweb/app.py +0 -95
  103. janito/version.py +0 -4
  104. {janito-2.3.1.dist-info → janito-2.5.0.dist-info}/WHEEL +0 -0
  105. {janito-2.3.1.dist-info → janito-2.5.0.dist-info}/entry_points.txt +0 -0
  106. {janito-2.3.1.dist-info → janito-2.5.0.dist-info}/licenses/LICENSE +0 -0
  107. {janito-2.3.1.dist-info → janito-2.5.0.dist-info}/top_level.txt +0 -0
@@ -1,16 +1,16 @@
1
- from janito.llm.model import LLMModelInfo
2
- from janito.providers.openai.model_info import MODEL_SPECS as OPENAI_MODEL_SPECS
3
-
4
- MODEL_SPECS = {
5
- "azure_openai_deployment": LLMModelInfo(
6
- name="azure_openai_deployment",
7
- context=OPENAI_MODEL_SPECS["gpt-4o"].context,
8
- max_input=OPENAI_MODEL_SPECS["gpt-4o"].max_input,
9
- max_cot=OPENAI_MODEL_SPECS["gpt-4o"].max_cot,
10
- max_response=OPENAI_MODEL_SPECS["gpt-4o"].max_response,
11
- thinking_supported=OPENAI_MODEL_SPECS["gpt-4o"].thinking_supported,
12
- default_temp=OPENAI_MODEL_SPECS["gpt-4o"].default_temp,
13
- open="azure_openai",
14
- driver="AzureOpenAIModelDriver",
15
- )
16
- }
1
+ from janito.llm.model import LLMModelInfo
2
+ from janito.providers.openai.model_info import MODEL_SPECS as OPENAI_MODEL_SPECS
3
+
4
+ MODEL_SPECS = {
5
+ "azure_openai_deployment": LLMModelInfo(
6
+ name="azure_openai_deployment",
7
+ context=OPENAI_MODEL_SPECS["gpt-4o"].context,
8
+ max_input=OPENAI_MODEL_SPECS["gpt-4o"].max_input,
9
+ max_cot=OPENAI_MODEL_SPECS["gpt-4o"].max_cot,
10
+ max_response=OPENAI_MODEL_SPECS["gpt-4o"].max_response,
11
+ thinking_supported=OPENAI_MODEL_SPECS["gpt-4o"].thinking_supported,
12
+ default_temp=OPENAI_MODEL_SPECS["gpt-4o"].default_temp,
13
+ open="azure_openai",
14
+ driver="AzureOpenAIModelDriver",
15
+ )
16
+ }
Binary file
@@ -8,9 +8,6 @@ STATIC_PROVIDER_METADATA = {
8
8
  "azure_openai": {
9
9
  "maintainer": "João Pinto <lamego.pinto@gmail.com>",
10
10
  },
11
- "mistralai": {
12
- "maintainer": "Needs maintainer",
13
- },
14
11
  "anthropic": {
15
12
  "maintainer": "Needs maintainer",
16
13
  },
@@ -1,26 +1,26 @@
1
- from typing import Type, Dict
2
- from janito.llm.provider import LLMProvider
3
-
4
-
5
- class LLMProviderRegistry:
6
- """
7
- Registry for LLM provider classes.
8
- """
9
-
10
- _providers: Dict[str, Type[LLMProvider]] = {}
11
-
12
- @classmethod
13
- def register(cls, name: str, provider_cls: Type[LLMProvider]):
14
- if name in cls._providers:
15
- raise ValueError(f"Provider '{name}' is already registered.")
16
- cls._providers[name] = provider_cls
17
-
18
- @classmethod
19
- def get(cls, name: str) -> Type[LLMProvider]:
20
- if name not in cls._providers:
21
- return None
22
- return cls._providers[name]
23
-
24
- @classmethod
25
- def list_providers(cls):
26
- return list(cls._providers.keys())
1
+ from typing import Type, Dict
2
+ from janito.llm.provider import LLMProvider
3
+
4
+
5
+ class LLMProviderRegistry:
6
+ """
7
+ Registry for LLM provider classes.
8
+ """
9
+
10
+ _providers: Dict[str, Type[LLMProvider]] = {}
11
+
12
+ @classmethod
13
+ def register(cls, name: str, provider_cls: Type[LLMProvider]):
14
+ if name in cls._providers:
15
+ raise ValueError(f"Provider '{name}' is already registered.")
16
+ cls._providers[name] = provider_cls
17
+
18
+ @classmethod
19
+ def get(cls, name: str) -> Type[LLMProvider]:
20
+ if name not in cls._providers:
21
+ return None
22
+ return cls._providers[name]
23
+
24
+ @classmethod
25
+ def list_providers(cls):
26
+ return list(cls._providers.keys())
janito/shell.bak.zip ADDED
Binary file
@@ -0,0 +1,33 @@
1
+ # Docstring Format Standard for Tools
2
+
3
+ All tool classes must use the following docstring style for schema compatibility and consistency:
4
+
5
+ - Use a single docstring in the tool class describing Args and Returns for all parameters of the `call` method.
6
+ - Args: List each parameter as `name (type): description` (type hints required for clarity).
7
+ - No blank lines between Args entries.
8
+ - Returns: Single line description, followed by examples if needed (no list markers).
9
+ - Keep formatting simple and consistent for schema compatibility.
10
+
11
+ Example:
12
+
13
+ class FindFilesTool(ToolBase):
14
+ """
15
+ Find files in one or more directories matching a pattern.
16
+
17
+ Args:
18
+ directories (list[str]): List of directories to search in.
19
+ pattern (str): File pattern to match. Uses Unix shell-style wildcards (fnmatch), e.g. '*.py', 'data_??.csv', '[a-z]*.txt'.
20
+
21
+ max_results (int, optional): Maximum number of results to return. Defaults to 100.
22
+ Returns:
23
+ str: Newline-separated list of matching file paths. Example:
24
+ "/path/to/file1.py\n/path/to/file2.py"
25
+ "Warning: Empty file pattern provided. Operation skipped."
26
+ """
27
+
28
+ # Tool Class Docstring Requirement
29
+
30
+ - All parameter documentation for OpenAI function tools must be in the class docstring, not the `call` method docstring.
31
+ - The class docstring is prepended to the tool's description in the OpenAI schema and is user-facing.
32
+ - Write class docstrings as concise, clear summaries of the tool's purpose and behavior, including parameter and return descriptions as shown above.
33
+ - Avoid implementation details; focus on what the tool does for the user.
janito/tools/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Tools Reference
2
+
3
+ This documentation has moved to [docs/TOOLS_REFERENCE.md](../../../docs/TOOLS_REFERENCE.md).
janito/tools/__init__.py CHANGED
@@ -4,17 +4,31 @@ from janito.tools.adapters.local import (
4
4
  )
5
5
 
6
6
 
7
- def get_local_tools_adapter(workdir=None):
7
+ def get_local_tools_adapter(workdir=None, allowed_permissions=None):
8
8
  # Use set_verbose_tools on the returned adapter to set verbosity as needed
9
+ import os
10
+ if workdir is not None and not os.path.exists(workdir):
11
+ os.makedirs(workdir, exist_ok=True)
12
+ # Permissions are now managed globally; ignore allowed_permissions argument except for backward compatibility
13
+ # Reuse the singleton adapter defined in janito.tools.adapters.local to maintain tool registrations
14
+ registry = _internal_local_tools_adapter
15
+ # Change workdir if requested
9
16
  if workdir is not None:
10
- import os
11
- if not os.path.exists(workdir):
12
- os.makedirs(workdir, exist_ok=True)
13
- return LocalToolsAdapter(workdir=workdir)
14
- return _internal_local_tools_adapter
17
+ try:
18
+ import os
19
+ if not os.path.exists(workdir):
20
+ os.makedirs(workdir, exist_ok=True)
21
+ os.chdir(workdir)
22
+ registry.workdir = workdir
23
+ except Exception:
24
+ pass
25
+ return registry
15
26
 
16
27
 
28
+ local_tools_adapter = _internal_local_tools_adapter
29
+
17
30
  __all__ = [
18
31
  "LocalToolsAdapter",
19
32
  "get_local_tools_adapter",
33
+ "local_tools_adapter",
20
34
  ]
@@ -1,62 +1,65 @@
1
- from .adapter import LocalToolsAdapter
2
-
3
- from .ask_user import AskUserTool
4
- from .copy_file import CopyFileTool
5
- from .create_directory import CreateDirectoryTool
6
- from .create_file import CreateFileTool
7
- from .fetch_url import FetchUrlTool
8
- from .find_files import FindFilesTool
9
- from .view_file import ViewFileTool
10
- from .move_file import MoveFileTool
11
- from .open_url import OpenUrlTool
12
- from .open_html_in_browser import OpenHtmlInBrowserTool
13
- from .python_code_run import PythonCodeRunTool
14
- from .python_command_run import PythonCommandRunTool
15
- from .python_file_run import PythonFileRunTool
16
- from .remove_directory import RemoveDirectoryTool
17
- from .remove_file import RemoveFileTool
18
- from .replace_text_in_file import ReplaceTextInFileTool
19
- from .run_bash_command import RunBashCommandTool
20
- from .run_powershell_command import RunPowershellCommandTool
21
- from .get_file_outline.core import GetFileOutlineTool
22
- from .get_file_outline.search_outline import SearchOutlineTool
23
- from .search_text.core import SearchTextTool
24
- from .validate_file_syntax.core import ValidateFileSyntaxTool
25
-
26
- # Singleton tools adapter with all standard tools registered
27
- import os
28
- local_tools_adapter = LocalToolsAdapter(workdir=os.getcwd())
29
-
30
- def get_local_tools_adapter(workdir=None):
31
- import os
32
- return LocalToolsAdapter(workdir=workdir or os.getcwd())
33
-
34
- # Register tools
35
- for tool_class in [
36
- AskUserTool,
37
- CopyFileTool,
38
- CreateDirectoryTool,
39
- CreateFileTool,
40
- FetchUrlTool,
41
- FindFilesTool,
42
- ViewFileTool,
43
- MoveFileTool,
44
- OpenUrlTool,
45
- OpenHtmlInBrowserTool,
46
- PythonCodeRunTool,
47
- PythonCommandRunTool,
48
- PythonFileRunTool,
49
- RemoveDirectoryTool,
50
- RemoveFileTool,
51
- ReplaceTextInFileTool,
52
- RunBashCommandTool,
53
- RunPowershellCommandTool,
54
- GetFileOutlineTool,
55
- SearchOutlineTool,
56
- SearchTextTool,
57
- ValidateFileSyntaxTool,
58
- ]:
59
- local_tools_adapter.register_tool(tool_class)
60
-
61
- # DEBUG: Print registered tools at startup
62
-
1
+ from .adapter import LocalToolsAdapter
2
+
3
+ from .ask_user import AskUserTool
4
+ from .copy_file import CopyFileTool
5
+ from .create_directory import CreateDirectoryTool
6
+ from .create_file import CreateFileTool
7
+ from .fetch_url import FetchUrlTool
8
+ from .find_files import FindFilesTool
9
+ from .view_file import ViewFileTool
10
+ from .move_file import MoveFileTool
11
+ from .open_url import OpenUrlTool
12
+ from .open_html_in_browser import OpenHtmlInBrowserTool
13
+ from .python_code_run import PythonCodeRunTool
14
+ from .python_command_run import PythonCommandRunTool
15
+ from .python_file_run import PythonFileRunTool
16
+ from .remove_directory import RemoveDirectoryTool
17
+ from .remove_file import RemoveFileTool
18
+ from .replace_text_in_file import ReplaceTextInFileTool
19
+ from .run_bash_command import RunBashCommandTool
20
+ from .run_powershell_command import RunPowershellCommandTool
21
+ from .get_file_outline.core import GetFileOutlineTool
22
+ from .get_file_outline.search_outline import SearchOutlineTool
23
+ from .search_text.core import SearchTextTool
24
+ from .validate_file_syntax.core import ValidateFileSyntaxTool
25
+
26
+ # Singleton tools adapter with all standard tools registered
27
+ from janito.tools.tool_base import ToolPermissions
28
+ import os
29
+ local_tools_adapter = LocalToolsAdapter(workdir=os.getcwd())
30
+
31
+ from janito.tools.permissions import get_global_allowed_permissions
32
+
33
+ def get_local_tools_adapter(workdir=None):
34
+ import os
35
+ return LocalToolsAdapter(workdir=workdir or os.getcwd())
36
+
37
+ # Register tools
38
+ for tool_class in [
39
+ AskUserTool,
40
+ CopyFileTool,
41
+ CreateDirectoryTool,
42
+ CreateFileTool,
43
+ FetchUrlTool,
44
+ FindFilesTool,
45
+ ViewFileTool,
46
+ MoveFileTool,
47
+ OpenUrlTool,
48
+ OpenHtmlInBrowserTool,
49
+ PythonCodeRunTool,
50
+ PythonCommandRunTool,
51
+ PythonFileRunTool,
52
+ RemoveDirectoryTool,
53
+ RemoveFileTool,
54
+ ReplaceTextInFileTool,
55
+ RunBashCommandTool,
56
+ RunPowershellCommandTool,
57
+ GetFileOutlineTool,
58
+ SearchOutlineTool,
59
+ SearchTextTool,
60
+ ValidateFileSyntaxTool,
61
+ ]:
62
+ local_tools_adapter.register_tool(tool_class)
63
+
64
+ # DEBUG: Print registered tools at startup
65
+
@@ -3,35 +3,22 @@ from janito.tools.tools_adapter import ToolsAdapterBase as ToolsAdapter
3
3
 
4
4
 
5
5
  class LocalToolsAdapter(ToolsAdapter):
6
- def set_execution_tools_enabled(self, enabled: bool):
7
- """
8
- Dynamically include or exclude execution tools from the enabled_tools set.
9
- If enabled_tools is None, all tools are enabled (default). If set, restricts enabled tools.
10
- """
11
- all_tool_names = set(self._tools.keys())
12
- exec_tool_names = {
13
- name for name, entry in self._tools.items()
14
- if getattr(entry["instance"], "provides_execution", False)
15
- }
16
- if self._enabled_tools is None:
17
- # If not restricted, create a new enabled-tools set excluding execution tools if disabling
18
- if enabled:
19
- self._enabled_tools = None # all tools enabled
20
- else:
21
- self._enabled_tools = all_tool_names - exec_tool_names
22
- else:
23
- if enabled:
24
- self._enabled_tools |= exec_tool_names
25
- else:
26
- self._enabled_tools -= exec_tool_names
6
+ """Local, in-process implementation of :class:`ToolsAdapterBase`.
27
7
 
28
- """
29
- Adapter for local, statically registered tools in the agent/tools system.
30
- Handles registration, lookup, enabling/disabling, listing, and now, tool execution (merged from executor).
8
+ This adapter keeps an **in-memory registry** of tool classes and manages
9
+ permission filtering (read/write/execute) as required by the janito CLI.
10
+
11
+ The legacy ``set_execution_tools_enabled()`` helper has been removed – use
12
+ ``janito.tools.permissions.set_global_allowed_permissions`` or
13
+ :py:meth:`LocalToolsAdapter.set_allowed_permissions` to adjust the
14
+ permission mask at runtime.
15
+
16
+ Apart from registration/lookup helpers the class derives all execution
17
+ logic from :class:`janito.tools.tools_adapter.ToolsAdapterBase`.
31
18
  """
32
19
 
33
- def __init__(self, tools=None, event_bus=None, enabled_tools=None, workdir=None):
34
- super().__init__(tools=tools, event_bus=event_bus, enabled_tools=enabled_tools)
20
+ def __init__(self, tools=None, event_bus=None, workdir=None):
21
+ super().__init__(tools=tools, event_bus=event_bus)
35
22
  self._tools: Dict[str, Dict[str, Any]] = {}
36
23
  self.workdir = workdir
37
24
  if self.workdir:
@@ -71,19 +58,13 @@ class LocalToolsAdapter(ToolsAdapter):
71
58
  return self._tools[name]["instance"] if name in self._tools else None
72
59
 
73
60
  def list_tools(self):
74
- if self._enabled_tools is None:
75
- return list(self._tools.keys())
76
- return [name for name in self._tools.keys() if name in self._enabled_tools]
61
+ return [name for name, entry in self._tools.items() if self.is_tool_allowed(entry["instance"])]
77
62
 
78
63
  def get_tool_classes(self):
79
- if self._enabled_tools is None:
80
- return [entry["class"] for entry in self._tools.values()]
81
- return [entry["class"] for name, entry in self._tools.items() if name in self._enabled_tools]
64
+ return [entry["class"] for entry in self._tools.values() if self.is_tool_allowed(entry["instance"])]
82
65
 
83
66
  def get_tools(self):
84
- if self._enabled_tools is None:
85
- return [entry["instance"] for entry in self._tools.values()]
86
- return [entry["instance"] for name, entry in self._tools.items() if name in self._enabled_tools]
67
+ return [entry["instance"] for entry in self._tools.values() if self.is_tool_allowed(entry["instance"])]
87
68
 
88
69
 
89
70
  def add_tool(self, tool):
@@ -109,6 +90,8 @@ class LocalToolsAdapter(ToolsAdapter):
109
90
 
110
91
  def register_local_tool(tool=None):
111
92
  def decorator(cls):
93
+ from janito.tools.tool_base import ToolPermissions
94
+ from janito.tools.permissions import get_global_allowed_permissions
112
95
  LocalToolsAdapter().register_tool(cls)
113
96
  return cls
114
97
 
@@ -1,4 +1,4 @@
1
- from janito.tools.tool_base import ToolBase
1
+ from janito.tools.tool_base import ToolBase, ToolPermissions
2
2
  from janito.tools.adapters.local.adapter import register_local_tool
3
3
 
4
4
  from rich import print as rich_print
@@ -20,15 +20,14 @@ class AskUserTool(ToolBase):
20
20
  Prompts the user for clarification or input with a question.
21
21
 
22
22
  Args:
23
- question (str): The question to ask the user.
24
-
23
+ question (str): The question to ask the user. This parameter is required and should be a string containing the prompt or question to display to the user.
25
24
  Returns:
26
25
  str: The user's response as a string. Example:
27
26
  - "Yes"
28
27
  - "No"
29
28
  - "Some detailed answer..."
30
29
  """
31
-
30
+ permissions = ToolPermissions(read=True)
32
31
  tool_name = "ask_user"
33
32
 
34
33
  def run(self, question: str) -> str:
@@ -2,7 +2,7 @@ import os
2
2
  import shutil
3
3
  from typing import List, Union
4
4
  from janito.tools.adapters.local.adapter import register_local_tool
5
- from janito.tools.tool_base import ToolBase
5
+ from janito.tools.tool_base import ToolBase, ToolPermissions
6
6
  from janito.tools.tool_utils import display_path
7
7
  from janito.report_events import ReportAction
8
8
  from janito.i18n import tr
@@ -21,7 +21,7 @@ class CopyFileTool(ToolBase):
21
21
  Returns:
22
22
  str: Status string for each copy operation.
23
23
  """
24
-
24
+ permissions = ToolPermissions(read=True, write=True)
25
25
  tool_name = "copy_file"
26
26
 
27
27
  def run(self, sources: str, target: str, overwrite: bool = False) -> str:
@@ -1,7 +1,7 @@
1
1
  from janito.tools.adapters.local.adapter import register_local_tool
2
2
 
3
3
  from janito.tools.tool_utils import display_path
4
- from janito.tools.tool_base import ToolBase
4
+ from janito.tools.tool_base import ToolBase, ToolPermissions
5
5
  from janito.report_events import ReportAction
6
6
  from janito.i18n import tr
7
7
  import os
@@ -18,7 +18,7 @@ class CreateDirectoryTool(ToolBase):
18
18
  - "5c5 Successfully created the directory at ..."
19
19
  - "5d7 Cannot create directory: ..."
20
20
  """
21
-
21
+ permissions = ToolPermissions(write=True)
22
22
  tool_name = "create_directory"
23
23
 
24
24
  def run(self, file_path: str) -> str:
@@ -2,7 +2,7 @@ import os
2
2
  from janito.tools.adapters.local.adapter import register_local_tool
3
3
 
4
4
  from janito.tools.tool_utils import display_path
5
- from janito.tools.tool_base import ToolBase
5
+ from janito.tools.tool_base import ToolBase, ToolPermissions
6
6
  from janito.report_events import ReportAction
7
7
  from janito.i18n import tr
8
8
 
@@ -25,7 +25,7 @@ class CreateFileTool(ToolBase):
25
25
 
26
26
  Note: Syntax validation is automatically performed after this operation.
27
27
  """
28
-
28
+ permissions = ToolPermissions(write=True)
29
29
  tool_name = "create_file"
30
30
 
31
31
  def run(self, file_path: str, content: str, overwrite: bool = False) -> str:
@@ -1,4 +1,4 @@
1
- from janito.tools.tool_base import ToolBase
1
+ from janito.tools.tool_base import ToolBase, ToolPermissions
2
2
  from janito.report_events import ReportAction
3
3
  from janito.tools.adapters.local.adapter import register_local_tool
4
4
  from janito.i18n import tr
@@ -19,7 +19,7 @@ class DeleteTextInFileTool(ToolBase):
19
19
  Returns:
20
20
  str: Status message indicating the result.
21
21
  """
22
-
22
+ permissions = ToolPermissions(read=True, write=True)
23
23
  tool_name = "delete_text_in_file"
24
24
 
25
25
  def run(
@@ -1,7 +1,7 @@
1
1
  import requests
2
2
  from bs4 import BeautifulSoup
3
3
  from janito.tools.adapters.local.adapter import register_local_tool
4
- from janito.tools.tool_base import ToolBase
4
+ from janito.tools.tool_base import ToolBase, ToolPermissions
5
5
  from janito.report_events import ReportAction
6
6
  from janito.i18n import tr
7
7
  from janito.tools.tool_utils import pluralize
@@ -21,7 +21,7 @@ class FetchUrlTool(ToolBase):
21
21
  - "No lines found for the provided search strings."
22
22
  - "Warning: Empty URL provided. Operation skipped."
23
23
  """
24
-
24
+ permissions = ToolPermissions(read=True)
25
25
  tool_name = "fetch_url"
26
26
 
27
27
  def run(self, url: str, search_strings: list[str] = None) -> str:
@@ -1,4 +1,4 @@
1
- from janito.tools.tool_base import ToolBase
1
+ from janito.tools.tool_base import ToolBase, ToolPermissions
2
2
  from janito.report_events import ReportAction
3
3
  from janito.tools.adapters.local.adapter import register_local_tool
4
4
  from janito.tools.tool_utils import pluralize, display_path
@@ -27,6 +27,7 @@ class FindFilesTool(ToolBase):
27
27
  "Warning: Empty file pattern provided. Operation skipped."
28
28
  """
29
29
 
30
+ permissions = ToolPermissions(read=True)
30
31
  tool_name = "find_files"
31
32
 
32
33
  def _match_directories(self, root, dirs, pat):
@@ -4,7 +4,7 @@ from .markdown_outline import parse_markdown_outline
4
4
  from janito.formatting import OutlineFormatter
5
5
  from .java_outline import parse_java_outline
6
6
  import os
7
- from janito.tools.tool_base import ToolBase
7
+ from janito.tools.tool_base import ToolBase, ToolPermissions
8
8
  from janito.report_events import ReportAction
9
9
  from janito.tools.tool_utils import display_path, pluralize
10
10
  from janito.i18n import tr
@@ -20,7 +20,7 @@ class GetFileOutlineTool(ToolBase):
20
20
  Args:
21
21
  file_path (str): Path to the file to outline.
22
22
  """
23
-
23
+ permissions = ToolPermissions(read=True)
24
24
  tool_name = "get_file_outline"
25
25
 
26
26
  def run(self, file_path: str) -> str:
@@ -1,4 +1,4 @@
1
- from janito.tools.tool_base import ToolBase
1
+ from janito.tools.tool_base import ToolBase, ToolPermissions
2
2
  from janito.report_events import ReportAction
3
3
 
4
4
 
@@ -11,7 +11,7 @@ class SearchOutlineTool(ToolBase):
11
11
  Returns:
12
12
  str: Outline search result or status message.
13
13
  """
14
-
14
+ permissions = ToolPermissions(read=True)
15
15
  tool_name = "search_outline"
16
16
 
17
17
  def run(self, file_path: str) -> str:
@@ -2,7 +2,7 @@ import os
2
2
  import shutil
3
3
  from janito.tools.adapters.local.adapter import register_local_tool
4
4
  from janito.tools.tool_utils import display_path
5
- from janito.tools.tool_base import ToolBase
5
+ from janito.tools.tool_base import ToolBase, ToolPermissions
6
6
  from janito.report_events import ReportAction
7
7
  from janito.i18n import tr
8
8
 
@@ -20,7 +20,7 @@ class MoveFileTool(ToolBase):
20
20
  Returns:
21
21
  str: Status message indicating the result.
22
22
  """
23
-
23
+ permissions = ToolPermissions(read=True, write=True)
24
24
  tool_name = "move_file"
25
25
 
26
26
  def run(
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  import webbrowser
3
3
  from janito.tools.adapters.local.adapter import register_local_tool
4
- from janito.tools.tool_base import ToolBase
4
+ from janito.tools.tool_base import ToolBase, ToolPermissions
5
5
  from janito.report_events import ReportAction
6
6
  from janito.i18n import tr
7
7
 
@@ -15,6 +15,7 @@ class OpenHtmlInBrowserTool(ToolBase):
15
15
  Returns:
16
16
  str: Status message indicating the result.
17
17
  """
18
+ permissions = ToolPermissions(read=True)
18
19
  tool_name = "open_html_in_browser"
19
20
 
20
21
  def run(self, file_path: str) -> str:
@@ -1,6 +1,6 @@
1
1
  import webbrowser
2
2
  from janito.tools.adapters.local.adapter import register_local_tool
3
- from janito.tools.tool_base import ToolBase
3
+ from janito.tools.tool_base import ToolBase, ToolPermissions
4
4
  from janito.report_events import ReportAction
5
5
  from janito.i18n import tr
6
6
 
@@ -15,7 +15,7 @@ class OpenUrlTool(ToolBase):
15
15
  Returns:
16
16
  str: Status message indicating the result.
17
17
  """
18
-
18
+ permissions = ToolPermissions(read=True)
19
19
  tool_name = "open_url"
20
20
 
21
21
  def run(self, url: str) -> str:
@@ -3,7 +3,7 @@ import os
3
3
  import sys
4
4
  import tempfile
5
5
  import threading
6
- from janito.tools.tool_base import ToolBase
6
+ from janito.tools.tool_base import ToolBase, ToolPermissions
7
7
  from janito.report_events import ReportAction
8
8
  from janito.tools.adapters.local.adapter import register_local_tool
9
9
  from janito.i18n import tr
@@ -14,14 +14,14 @@ class PythonCodeRunTool(ToolBase):
14
14
  """
15
15
  Tool to execute Python code by passing it to the interpreter via standard input (stdin).
16
16
 
17
- Parameters:
17
+ Args:
18
18
  code (str): The Python code to execute as a string.
19
19
  timeout (int): Timeout in seconds for the command. Defaults to 60.
20
20
 
21
21
  Returns:
22
22
  str: Output and status message, or file paths/line counts if output is large.
23
23
  """
24
- provides_execution = True
24
+ permissions = ToolPermissions(execute=True)
25
25
  tool_name = "python_code_run"
26
26
 
27
27
  def run(self, code: str, timeout: int = 60) -> str:
@@ -3,7 +3,7 @@ import os
3
3
  import sys
4
4
  import tempfile
5
5
  import threading
6
- from janito.tools.tool_base import ToolBase
6
+ from janito.tools.tool_base import ToolBase, ToolPermissions
7
7
  from janito.report_events import ReportAction
8
8
  from janito.tools.adapters.local.adapter import register_local_tool
9
9
  from janito.i18n import tr
@@ -14,14 +14,14 @@ class PythonCommandRunTool(ToolBase):
14
14
  """
15
15
  Tool to execute Python code using the `python -c` command-line flag.
16
16
 
17
- Parameters:
17
+ Args:
18
18
  code (str): The Python code to execute as a string.
19
19
  timeout (int): Timeout in seconds for the command. Defaults to 60.
20
20
 
21
21
  Returns:
22
22
  str: Output and status message, or file paths/line counts if output is large.
23
23
  """
24
- provides_execution = True
24
+ permissions = ToolPermissions(execute=True)
25
25
  tool_name = "python_command_run"
26
26
 
27
27
  def run(self, code: str, timeout: int = 60) -> str: