janito 2.3.0__py3-none-any.whl → 2.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.
- janito/__init__.py +6 -6
- janito/_version.py +57 -0
- janito/agent/setup_agent.py +92 -18
- janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +44 -0
- janito/cli/chat_mode/bindings.py +21 -2
- janito/cli/chat_mode/chat_entry.py +2 -3
- janito/cli/chat_mode/prompt_style.py +5 -0
- janito/cli/chat_mode/session.py +80 -94
- janito/cli/chat_mode/session_profile_select.py +80 -0
- janito/cli/chat_mode/shell/autocomplete.py +21 -21
- janito/cli/chat_mode/shell/commands/__init__.py +13 -7
- janito/cli/chat_mode/shell/commands/_priv_check.py +5 -0
- janito/cli/chat_mode/shell/commands/clear.py +12 -12
- janito/cli/chat_mode/shell/commands/conversation_restart.py +30 -0
- janito/cli/chat_mode/shell/commands/execute.py +42 -0
- janito/cli/chat_mode/shell/commands/help.py +6 -3
- janito/cli/chat_mode/shell/commands/model.py +28 -0
- janito/cli/chat_mode/shell/commands/multi.py +51 -51
- janito/cli/chat_mode/shell/commands/read.py +37 -0
- janito/cli/chat_mode/shell/commands/tools.py +45 -18
- janito/cli/chat_mode/shell/commands/write.py +37 -0
- janito/cli/chat_mode/shell/commands.bak.zip +0 -0
- janito/cli/chat_mode/shell/input_history.py +62 -62
- janito/cli/chat_mode/shell/session.bak.zip +0 -0
- janito/cli/chat_mode/toolbar.py +44 -27
- janito/cli/cli_commands/list_models.py +35 -35
- janito/cli/cli_commands/list_providers.py +9 -9
- janito/cli/cli_commands/list_tools.py +86 -53
- janito/cli/cli_commands/model_selection.py +50 -50
- janito/cli/cli_commands/set_api_key.py +19 -19
- janito/cli/cli_commands/show_config.py +51 -51
- janito/cli/cli_commands/show_system_prompt.py +105 -62
- janito/cli/config.py +5 -6
- janito/cli/core/__init__.py +4 -4
- janito/cli/core/event_logger.py +59 -59
- janito/cli/core/runner.py +25 -18
- janito/cli/core/setters.py +10 -1
- janito/cli/core/unsetters.py +54 -54
- janito/cli/main_cli.py +28 -5
- janito/cli/prompt_core.py +18 -2
- janito/cli/prompt_setup.py +56 -0
- janito/cli/single_shot_mode/__init__.py +6 -6
- janito/cli/single_shot_mode/handler.py +14 -73
- janito/cli/verbose_output.py +1 -1
- janito/config.py +5 -5
- janito/config_manager.py +13 -0
- janito/drivers/anthropic/driver.py +113 -113
- janito/drivers/dashscope.bak.zip +0 -0
- janito/drivers/openai/README.md +20 -0
- janito/drivers/openai_responses.bak.zip +0 -0
- janito/event_bus/event.py +2 -2
- janito/formatting_token.py +54 -54
- janito/i18n/__init__.py +35 -35
- janito/i18n/messages.py +23 -23
- janito/i18n/pt.py +46 -47
- janito/llm/README.md +23 -0
- janito/llm/__init__.py +5 -5
- janito/llm/agent.py +507 -443
- janito/llm/driver.py +8 -0
- janito/llm/driver_config_builder.py +34 -34
- janito/llm/driver_input.py +12 -12
- janito/llm/message_parts.py +60 -60
- janito/llm/model.py +38 -38
- janito/llm/provider.py +196 -196
- janito/provider_registry.py +8 -6
- janito/providers/anthropic/model_info.py +22 -22
- janito/providers/anthropic/provider.py +2 -0
- janito/providers/azure_openai/provider.py +3 -0
- janito/providers/dashscope.bak.zip +0 -0
- janito/providers/deepseek/__init__.py +1 -1
- janito/providers/deepseek/model_info.py +16 -16
- janito/providers/deepseek/provider.py +94 -91
- janito/providers/google/provider.py +3 -0
- janito/providers/mistralai/provider.py +3 -0
- janito/providers/openai/provider.py +4 -0
- janito/providers/registry.py +26 -26
- janito/shell.bak.zip +0 -0
- janito/tools/DOCSTRING_STANDARD.txt +33 -0
- janito/tools/README.md +3 -0
- janito/tools/__init__.py +20 -6
- janito/tools/adapters/__init__.py +1 -1
- janito/tools/adapters/local/__init__.py +65 -62
- janito/tools/adapters/local/adapter.py +18 -35
- janito/tools/adapters/local/ask_user.py +101 -102
- janito/tools/adapters/local/copy_file.py +84 -84
- janito/tools/adapters/local/create_directory.py +69 -69
- janito/tools/adapters/local/create_file.py +82 -82
- janito/tools/adapters/local/delete_text_in_file.py +2 -2
- janito/tools/adapters/local/fetch_url.py +97 -97
- janito/tools/adapters/local/find_files.py +139 -138
- janito/tools/adapters/local/get_file_outline/__init__.py +1 -1
- janito/tools/adapters/local/get_file_outline/core.py +117 -117
- janito/tools/adapters/local/get_file_outline/java_outline.py +40 -40
- janito/tools/adapters/local/get_file_outline/markdown_outline.py +14 -14
- janito/tools/adapters/local/get_file_outline/python_outline.py +303 -303
- janito/tools/adapters/local/get_file_outline/python_outline_v2.py +156 -156
- janito/tools/adapters/local/get_file_outline/search_outline.py +33 -33
- janito/tools/adapters/local/move_file.py +2 -2
- janito/tools/adapters/local/open_html_in_browser.py +2 -1
- janito/tools/adapters/local/open_url.py +2 -2
- janito/tools/adapters/local/python_code_run.py +166 -166
- janito/tools/adapters/local/python_command_run.py +164 -164
- janito/tools/adapters/local/python_file_run.py +163 -163
- janito/tools/adapters/local/remove_directory.py +2 -2
- janito/tools/adapters/local/remove_file.py +2 -2
- janito/tools/adapters/local/replace_text_in_file.py +2 -2
- janito/tools/adapters/local/run_bash_command.py +176 -176
- janito/tools/adapters/local/run_powershell_command.py +219 -219
- janito/tools/adapters/local/search_text/__init__.py +1 -1
- janito/tools/adapters/local/search_text/core.py +201 -201
- janito/tools/adapters/local/search_text/pattern_utils.py +73 -73
- janito/tools/adapters/local/search_text/traverse_directory.py +145 -145
- janito/tools/adapters/local/validate_file_syntax/__init__.py +1 -1
- janito/tools/adapters/local/validate_file_syntax/core.py +106 -106
- janito/tools/adapters/local/validate_file_syntax/css_validator.py +35 -35
- janito/tools/adapters/local/validate_file_syntax/html_validator.py +93 -93
- janito/tools/adapters/local/validate_file_syntax/js_validator.py +27 -27
- janito/tools/adapters/local/validate_file_syntax/json_validator.py +6 -6
- janito/tools/adapters/local/validate_file_syntax/markdown_validator.py +109 -109
- janito/tools/adapters/local/validate_file_syntax/ps1_validator.py +32 -32
- janito/tools/adapters/local/validate_file_syntax/python_validator.py +5 -5
- janito/tools/adapters/local/validate_file_syntax/xml_validator.py +11 -11
- janito/tools/adapters/local/validate_file_syntax/yaml_validator.py +6 -6
- janito/tools/adapters/local/view_file.py +168 -167
- janito/tools/inspect_registry.py +17 -17
- janito/tools/outline_file.bak.zip +0 -0
- janito/tools/permissions.py +45 -0
- janito/tools/permissions_parse.py +12 -0
- janito/tools/tool_base.py +118 -105
- janito/tools/tool_events.py +58 -58
- janito/tools/tool_run_exception.py +12 -12
- janito/tools/tool_use_tracker.py +81 -81
- janito/tools/tool_utils.py +43 -45
- janito/tools/tools_adapter.py +25 -20
- janito/tools/tools_schema.py +104 -104
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/METADATA +425 -388
- janito-2.4.0.dist-info/RECORD +195 -0
- janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +0 -13
- janito/agent/templates/profiles/system_prompt_template_main.txt.j2 +0 -37
- janito/cli/chat_mode/shell/commands/edit.py +0 -25
- janito/cli/chat_mode/shell/commands/exec.py +0 -27
- janito/cli/chat_mode/shell/commands/termweb_log.py +0 -92
- janito/cli/termweb_starter.py +0 -122
- janito/termweb/app.py +0 -95
- janito/version.py +0 -4
- janito-2.3.0.dist-info/RECORD +0 -181
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/WHEEL +0 -0
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/entry_points.txt +0 -0
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/licenses/LICENSE +0 -0
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/top_level.txt +0 -0
@@ -1,91 +1,94 @@
|
|
1
|
-
from janito.llm.provider import LLMProvider
|
2
|
-
from janito.llm.model import LLMModelInfo
|
3
|
-
from janito.llm.auth import LLMAuthManager
|
4
|
-
from janito.llm.driver_config import LLMDriverConfig
|
5
|
-
from janito.drivers.openai.driver import OpenAIModelDriver
|
6
|
-
from janito.tools import get_local_tools_adapter
|
7
|
-
from janito.providers.registry import LLMProviderRegistry
|
8
|
-
from .model_info import MODEL_SPECS
|
9
|
-
from queue import Queue
|
10
|
-
|
11
|
-
available = OpenAIModelDriver.available
|
12
|
-
unavailable_reason = OpenAIModelDriver.unavailable_reason
|
13
|
-
|
14
|
-
|
15
|
-
class DeepseekProvider(LLMProvider):
|
16
|
-
name = "deepseek"
|
17
|
-
maintainer = "Needs maintainer"
|
18
|
-
MODEL_SPECS = MODEL_SPECS
|
19
|
-
DEFAULT_MODEL = "deepseek-chat" # Options: deepseek-chat, deepseek-reasoner
|
20
|
-
|
21
|
-
def __init__(
|
22
|
-
self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
|
23
|
-
):
|
24
|
-
if
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
self.
|
29
|
-
|
30
|
-
self.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
if not
|
37
|
-
self._driver_config.
|
38
|
-
|
39
|
-
self.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
driver
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
#
|
73
|
-
|
74
|
-
|
75
|
-
)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
self.
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
1
|
+
from janito.llm.provider import LLMProvider
|
2
|
+
from janito.llm.model import LLMModelInfo
|
3
|
+
from janito.llm.auth import LLMAuthManager
|
4
|
+
from janito.llm.driver_config import LLMDriverConfig
|
5
|
+
from janito.drivers.openai.driver import OpenAIModelDriver
|
6
|
+
from janito.tools import get_local_tools_adapter
|
7
|
+
from janito.providers.registry import LLMProviderRegistry
|
8
|
+
from .model_info import MODEL_SPECS
|
9
|
+
from queue import Queue
|
10
|
+
|
11
|
+
available = OpenAIModelDriver.available
|
12
|
+
unavailable_reason = OpenAIModelDriver.unavailable_reason
|
13
|
+
|
14
|
+
|
15
|
+
class DeepseekProvider(LLMProvider):
|
16
|
+
name = "deepseek"
|
17
|
+
maintainer = "Needs maintainer"
|
18
|
+
MODEL_SPECS = MODEL_SPECS
|
19
|
+
DEFAULT_MODEL = "deepseek-chat" # Options: deepseek-chat, deepseek-reasoner
|
20
|
+
|
21
|
+
def __init__(
|
22
|
+
self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
|
23
|
+
):
|
24
|
+
# Always set a tools adapter so that even if the driver is unavailable,
|
25
|
+
# generic code paths that expect provider.execute_tool() continue to work.
|
26
|
+
self._tools_adapter = get_local_tools_adapter()
|
27
|
+
if not self.available:
|
28
|
+
self._driver = None
|
29
|
+
else:
|
30
|
+
self.auth_manager = auth_manager or LLMAuthManager()
|
31
|
+
self._api_key = self.auth_manager.get_credentials(type(self).name)
|
32
|
+
self._tools_adapter = get_local_tools_adapter()
|
33
|
+
self._driver_config = config or LLMDriverConfig(model=None)
|
34
|
+
if not self._driver_config.model:
|
35
|
+
self._driver_config.model = self.DEFAULT_MODEL
|
36
|
+
if not self._driver_config.api_key:
|
37
|
+
self._driver_config.api_key = self._api_key
|
38
|
+
# Set DeepSeek public endpoint as default base_url if not provided
|
39
|
+
if not getattr(self._driver_config, "base_url", None):
|
40
|
+
self._driver_config.base_url = "https://api.deepseek.com/v1"
|
41
|
+
self.fill_missing_device_info(self._driver_config)
|
42
|
+
self._driver = None # to be provided by factory/agent
|
43
|
+
|
44
|
+
@property
|
45
|
+
def driver(self) -> OpenAIModelDriver:
|
46
|
+
if not self.available:
|
47
|
+
raise ImportError(f"OpenAIProvider unavailable: {self.unavailable_reason}")
|
48
|
+
return self._driver
|
49
|
+
|
50
|
+
@property
|
51
|
+
def available(self):
|
52
|
+
return available
|
53
|
+
|
54
|
+
@property
|
55
|
+
def unavailable_reason(self):
|
56
|
+
return unavailable_reason
|
57
|
+
|
58
|
+
def create_driver(self):
|
59
|
+
"""
|
60
|
+
Creates and returns a new OpenAIModelDriver instance with input/output queues.
|
61
|
+
"""
|
62
|
+
driver = OpenAIModelDriver(
|
63
|
+
tools_adapter=self._tools_adapter, provider_name=self.name
|
64
|
+
)
|
65
|
+
driver.config = self._driver_config
|
66
|
+
# NOTE: The caller is responsible for calling driver.start() if background processing is needed.
|
67
|
+
return driver
|
68
|
+
|
69
|
+
def create_agent(self, tools_adapter=None, agent_name: str = None, **kwargs):
|
70
|
+
from janito.llm.agent import LLMAgent
|
71
|
+
|
72
|
+
# Always create a new driver with the passed-in tools_adapter
|
73
|
+
if tools_adapter is None:
|
74
|
+
tools_adapter = get_local_tools_adapter()
|
75
|
+
# Should use new-style driver construction via queues/factory (handled elsewhere)
|
76
|
+
raise NotImplementedError(
|
77
|
+
"create_agent must be constructed via new factory using input/output queues and config."
|
78
|
+
)
|
79
|
+
|
80
|
+
@property
|
81
|
+
def model_name(self):
|
82
|
+
return self._driver_config.model
|
83
|
+
|
84
|
+
@property
|
85
|
+
def driver_config(self):
|
86
|
+
"""Public, read-only access to the provider's LLMDriverConfig object."""
|
87
|
+
return self._driver_config
|
88
|
+
|
89
|
+
def execute_tool(self, tool_name: str, event_bus, *args, **kwargs):
|
90
|
+
self._tools_adapter.event_bus = event_bus
|
91
|
+
return self._tools_adapter.execute_by_name(tool_name, *args, **kwargs)
|
92
|
+
|
93
|
+
|
94
|
+
LLMProviderRegistry.register(DeepseekProvider.name, DeepseekProvider)
|
@@ -22,6 +22,9 @@ class GoogleProvider(LLMProvider):
|
|
22
22
|
def __init__(
|
23
23
|
self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
|
24
24
|
):
|
25
|
+
# Always have a tools adapter available to avoid AttributeError downstream when
|
26
|
+
# the driver is missing but other logic still relies on tools execution.
|
27
|
+
self._tools_adapter = get_local_tools_adapter()
|
25
28
|
if not self.available:
|
26
29
|
self._driver = None
|
27
30
|
else:
|
@@ -24,6 +24,9 @@ class MistralAIProvider(LLMProvider):
|
|
24
24
|
def __init__(
|
25
25
|
self, config: LLMDriverConfig = None, auth_manager: LLMAuthManager = None
|
26
26
|
):
|
27
|
+
# Always instantiate a tools adapter so that provider.execute_tool() remains functional
|
28
|
+
# even when the driver cannot be constructed due to missing dependencies.
|
29
|
+
self._tools_adapter = get_local_tools_adapter()
|
27
30
|
if not self.available:
|
28
31
|
self._driver = None
|
29
32
|
return
|
@@ -24,6 +24,10 @@ class OpenAIProvider(LLMProvider):
|
|
24
24
|
self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
|
25
25
|
):
|
26
26
|
if not self.available:
|
27
|
+
# Even when the OpenAI driver is unavailable we still need a tools adapter
|
28
|
+
# so that any generic logic that expects `execute_tool()` to work does not
|
29
|
+
# crash with an AttributeError when it tries to access `self._tools_adapter`.
|
30
|
+
self._tools_adapter = get_local_tools_adapter()
|
27
31
|
self._driver = None
|
28
32
|
else:
|
29
33
|
self.auth_manager = auth_manager or LLMAuthManager()
|
janito/providers/registry.py
CHANGED
@@ -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
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
|
-
|
11
|
-
|
12
|
-
os.
|
13
|
-
|
14
|
-
|
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 +1 @@
|
|
1
|
-
# Tools providers package: for plug-and-play tool collections, integrations, and adapters.
|
1
|
+
# Tools providers package: for plug-and-play tool collections, integrations, and adapters.
|
@@ -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
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
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
|
-
|
30
|
-
|
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,
|
34
|
-
super().__init__(tools=tools, event_bus=event_bus
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
|