janito 3.6.1__py3-none-any.whl → 3.7.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/README.md +4 -7
- janito/cli/chat_mode/bindings.py +0 -50
- janito/cli/chat_mode/session.py +1 -12
- janito/cli/chat_mode/shell/commands/multi.py +0 -5
- janito/cli/chat_mode/shell/commands/security/allowed_sites.py +33 -47
- janito/cli/cli_commands/list_plugins.py +43 -52
- janito/cli/cli_commands/list_tools.py +1 -6
- janito/cli/core/getters.py +0 -3
- janito/cli/core/model_guesser.py +24 -40
- janito/cli/main_cli.py +13 -10
- janito/cli/prompt_core.py +9 -47
- janito/cli/rich_terminal_reporter.py +4 -4
- janito/docs/GETTING_STARTED.md +9 -8
- janito/drivers/openai/driver.py +0 -1
- janito/drivers/zai/driver.py +0 -1
- janito/i18n/it.py +46 -46
- janito/llm/agent.py +16 -32
- janito/llm/auth_utils.py +5 -14
- janito/llm/driver.py +0 -8
- janito/plugins/__init__.py +12 -31
- janito/plugins/auto_loader.py +11 -12
- janito/plugins/auto_loader_fixed.py +11 -12
- janito/{plugin_system → plugins}/base.py +2 -5
- janito/plugins/builtin.py +1 -15
- janito/plugins/core_adapter.py +11 -89
- janito/plugins/core_loader.py +120 -0
- janito/plugins/core_loader_fixed.py +125 -0
- janito/plugins/discovery.py +5 -5
- janito/plugins/discovery_core.py +9 -14
- janito/plugins/manager.py +1 -1
- janito/providers/__init__.py +0 -1
- janito/providers/moonshot/model_info.py +7 -7
- janito/providers/moonshot/provider.py +1 -1
- janito/tools/__init__.py +7 -41
- janito/tools/adapters/__init__.py +1 -6
- janito/tools/adapters/local/__init__.py +70 -7
- janito/{plugins/tools/core → tools/adapters/local}/ask_user.py +3 -3
- janito/tools/adapters/local/copy_file.py +87 -0
- janito/tools/adapters/local/create_file.py +138 -0
- janito/{plugins/tools/core → tools/adapters/local}/fetch_url.py +23 -20
- janito/tools/adapters/local/move_file.py +131 -0
- janito/{plugins/tools/core → tools/adapters/local}/python_code_run.py +7 -23
- janito/{plugins/tools/core → tools/adapters/local}/python_command_run.py +5 -21
- janito/{plugins/tools/core → tools/adapters/local}/python_file_run.py +5 -21
- janito/tools/adapters/local/remove_file.py +58 -0
- janito/{plugins/tools/core → tools/adapters/local}/replace_text_in_file.py +4 -4
- janito/{plugins/tools/core → tools/adapters/local}/run_bash_command.py +3 -3
- janito/{plugins/tools/core → tools/adapters/local}/run_powershell_command.py +3 -3
- janito/{plugins/tools/core → tools/adapters/local}/show_image.py +6 -15
- janito/{plugins/core/imagedisplay/tools → tools/adapters/local}/show_image_grid.py +5 -13
- janito/tools/adapters/local/view_file.py +172 -0
- janito/tools/function_adapter.py +65 -0
- janito/tools/loop_protection_decorator.py +117 -114
- janito-3.7.0.dist-info/METADATA +84 -0
- janito-3.7.0.dist-info/RECORD +264 -0
- janito/cli/cli_commands/check_tools.py +0 -212
- janito/data/blocked.txt +0 -96
- janito/llm/cancellation_manager.py +0 -63
- janito/llm/enter_cancellation.py +0 -107
- janito/plugin_system/__init__.py +0 -10
- janito/plugin_system/core_loader.py +0 -217
- janito/plugin_system/core_loader_fixed.py +0 -225
- janito/plugins/core/__init__.py +0 -7
- janito/plugins/core/codeanalyzer/__init__.py +0 -43
- janito/plugins/core/filemanager/__init__.py +0 -124
- janito/plugins/core/filemanager/tools/copy_file.py +0 -87
- janito/plugins/core/filemanager/tools/create_file.py +0 -87
- janito/plugins/core/filemanager/tools/move_file.py +0 -131
- janito/plugins/core/filemanager/tools/remove_file.py +0 -58
- janito/plugins/core/filemanager/tools/replace_text_in_file.py +0 -270
- janito/plugins/core/filemanager/tools/view_file.py +0 -172
- janito/plugins/core/imagedisplay/__init__.py +0 -14
- janito/plugins/core/imagedisplay/plugin.py +0 -51
- janito/plugins/core/imagedisplay/tools/__init__.py +0 -1
- janito/plugins/core/imagedisplay/tools/show_image.py +0 -83
- janito/plugins/core/system/__init__.py +0 -23
- janito/plugins/core/system/tools/run_bash_command.py +0 -204
- janito/plugins/core/system/tools/run_powershell_command.py +0 -234
- janito/plugins/dev/__init__.py +0 -7
- janito/plugins/dev/pythondev/__init__.py +0 -37
- janito/plugins/dev/visualization/__init__.py +0 -23
- janito/plugins/example_plugin.py +0 -108
- janito/plugins/tools/__init__.py +0 -39
- janito/plugins/tools/core/__init__.py +0 -65
- janito/plugins/tools/core/copy_file.py +0 -87
- janito/plugins/tools/core/create_directory.py +0 -70
- janito/plugins/tools/core/create_file.py +0 -138
- janito/plugins/tools/core/decorators.py +0 -19
- janito/plugins/tools/core/delete_text_in_file.py +0 -134
- janito/plugins/tools/core/find_files.py +0 -143
- janito/plugins/tools/core/get_file_outline/__init__.py +0 -7
- janito/plugins/tools/core/get_file_outline/core.py +0 -122
- janito/plugins/tools/core/get_file_outline/java_outline.py +0 -47
- janito/plugins/tools/core/get_file_outline/markdown_outline.py +0 -14
- janito/plugins/tools/core/get_file_outline/python_outline.py +0 -303
- janito/plugins/tools/core/get_file_outline/search_outline.py +0 -36
- janito/plugins/tools/core/move_file.py +0 -131
- janito/plugins/tools/core/open_html_in_browser.py +0 -51
- janito/plugins/tools/core/open_url.py +0 -37
- janito/plugins/tools/core/read_chart.py +0 -259
- janito/plugins/tools/core/read_files.py +0 -58
- janito/plugins/tools/core/remove_directory.py +0 -55
- janito/plugins/tools/core/remove_file.py +0 -58
- janito/plugins/tools/core/search_text/__init__.py +0 -7
- janito/plugins/tools/core/search_text/core.py +0 -205
- janito/plugins/tools/core/search_text/match_lines.py +0 -67
- janito/plugins/tools/core/search_text/pattern_utils.py +0 -73
- janito/plugins/tools/core/search_text/traverse_directory.py +0 -145
- janito/plugins/tools/core/show_image_grid.py +0 -85
- janito/plugins/tools/core/validate_file_syntax/__init__.py +0 -7
- janito/plugins/tools/core/validate_file_syntax/core.py +0 -114
- janito/plugins/tools/core/validate_file_syntax/css_validator.py +0 -35
- janito/plugins/tools/core/validate_file_syntax/html_validator.py +0 -100
- janito/plugins/tools/core/validate_file_syntax/jinja2_validator.py +0 -50
- janito/plugins/tools/core/validate_file_syntax/js_validator.py +0 -27
- janito/plugins/tools/core/validate_file_syntax/json_validator.py +0 -6
- janito/plugins/tools/core/validate_file_syntax/markdown_validator.py +0 -109
- janito/plugins/tools/core/validate_file_syntax/ps1_validator.py +0 -32
- janito/plugins/tools/core/validate_file_syntax/python_validator.py +0 -5
- janito/plugins/tools/core/validate_file_syntax/xml_validator.py +0 -11
- janito/plugins/tools/core/validate_file_syntax/yaml_validator.py +0 -6
- janito/plugins/tools/core/view_file.py +0 -172
- janito/plugins/ui/__init__.py +0 -7
- janito/plugins/ui/userinterface/__init__.py +0 -16
- janito/plugins/ui/userinterface/tools/ask_user.py +0 -110
- janito/plugins/web/__init__.py +0 -7
- janito/plugins/web/webtools/__init__.py +0 -23
- janito/providers/together/__init__.py +0 -1
- janito/providers/together/model_info.py +0 -69
- janito/providers/together/provider.py +0 -108
- janito/tools/blocked_sites.py +0 -74
- janito/tools/cli_initializer.py +0 -88
- janito/tools/initialize.py +0 -70
- janito-3.6.1.dist-info/METADATA +0 -228
- janito-3.6.1.dist-info/RECORD +0 -339
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/create_directory.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/delete_text_in_file.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/find_files.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/__init__.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/core.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/java_outline.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/markdown_outline.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/python_outline.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/search_outline.py +0 -0
- /janito/{plugins/web/webtools/tools → tools/adapters/local}/open_html_in_browser.py +0 -0
- /janito/{plugins/web/webtools/tools → tools/adapters/local}/open_url.py +0 -0
- /janito/{plugins/dev/visualization/tools → tools/adapters/local}/read_chart.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/read_files.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/remove_directory.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/__init__.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/core.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/match_lines.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/pattern_utils.py +0 -0
- /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/traverse_directory.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/__init__.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/core.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/css_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/html_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/jinja2_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/js_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/json_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/markdown_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/ps1_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/python_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/xml_validator.py +0 -0
- /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/yaml_validator.py +0 -0
- {janito-3.6.1.dist-info → janito-3.7.0.dist-info}/WHEEL +0 -0
- {janito-3.6.1.dist-info → janito-3.7.0.dist-info}/entry_points.txt +0 -0
- {janito-3.6.1.dist-info → janito-3.7.0.dist-info}/licenses/LICENSE +0 -0
- {janito-3.6.1.dist-info → janito-3.7.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
"""
|
2
|
+
Core plugin loader that properly handles function-based plugins.
|
3
|
+
|
4
|
+
This module provides a simplified approach to load core plugins
|
5
|
+
without the complex discovery mechanism.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import importlib.util
|
9
|
+
import sys
|
10
|
+
from pathlib import Path
|
11
|
+
from typing import Optional
|
12
|
+
|
13
|
+
from janito.plugins.base import Plugin, PluginMetadata
|
14
|
+
from janito.tools.function_adapter import create_function_tool
|
15
|
+
from janito.tools.tool_base import ToolBase
|
16
|
+
|
17
|
+
|
18
|
+
class CorePlugin(Plugin):
|
19
|
+
"""Simple core plugin implementation."""
|
20
|
+
|
21
|
+
def __init__(self, name: str, description: str, tools: list):
|
22
|
+
super().__init__()
|
23
|
+
self._plugin_name = name
|
24
|
+
self._description = description
|
25
|
+
self._tools = tools
|
26
|
+
self._tool_classes = []
|
27
|
+
|
28
|
+
def get_metadata(self) -> PluginMetadata:
|
29
|
+
return PluginMetadata(
|
30
|
+
name=self._plugin_name,
|
31
|
+
version="1.0.0",
|
32
|
+
description=self._description,
|
33
|
+
author="Janito",
|
34
|
+
license="MIT",
|
35
|
+
)
|
36
|
+
|
37
|
+
def get_tools(self) -> list:
|
38
|
+
return self._tool_classes
|
39
|
+
|
40
|
+
def initialize(self):
|
41
|
+
"""Initialize by creating tool classes."""
|
42
|
+
self._tool_classes = []
|
43
|
+
for tool_func in self._tools:
|
44
|
+
if callable(tool_func):
|
45
|
+
tool_class = create_function_tool(tool_func)
|
46
|
+
self._tool_classes.append(tool_class)
|
47
|
+
|
48
|
+
|
49
|
+
def load_core_plugin(plugin_name: str) -> Optional[Plugin]:
|
50
|
+
"""
|
51
|
+
Load a core plugin by name.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
plugin_name: Name of the plugin (e.g., 'core.filemanager')
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
Plugin instance if loaded successfully
|
58
|
+
"""
|
59
|
+
try:
|
60
|
+
# Parse plugin name
|
61
|
+
if "." not in plugin_name:
|
62
|
+
return None
|
63
|
+
|
64
|
+
parts = plugin_name.split(".")
|
65
|
+
if len(parts) != 2:
|
66
|
+
return None
|
67
|
+
|
68
|
+
package_name, submodule_name = parts
|
69
|
+
|
70
|
+
# Build path to plugin
|
71
|
+
plugin_path = Path("plugins") / package_name / submodule_name / "__init__.py"
|
72
|
+
if not plugin_path.exists():
|
73
|
+
return None
|
74
|
+
|
75
|
+
# Load the module
|
76
|
+
spec = importlib.util.spec_from_file_location(plugin_name, plugin_path)
|
77
|
+
if spec is None or spec.loader is None:
|
78
|
+
return None
|
79
|
+
|
80
|
+
module = importlib.util.module_from_spec(spec)
|
81
|
+
spec.loader.exec_module(module)
|
82
|
+
|
83
|
+
# Get plugin info
|
84
|
+
name = getattr(module, "__plugin_name__", plugin_name)
|
85
|
+
description = getattr(module, "__plugin_description__", f"Core plugin: {plugin_name}")
|
86
|
+
tools = getattr(module, "__plugin_tools__", [])
|
87
|
+
|
88
|
+
if not tools:
|
89
|
+
return None
|
90
|
+
|
91
|
+
# Create plugin
|
92
|
+
plugin = CorePlugin(name, description, tools)
|
93
|
+
plugin.initialize()
|
94
|
+
return plugin
|
95
|
+
|
96
|
+
except Exception as e:
|
97
|
+
print(f"Error loading core plugin {plugin_name}: {e}")
|
98
|
+
return None
|
99
|
+
|
100
|
+
|
101
|
+
def get_core_plugins() -> list:
|
102
|
+
"""Get list of all available core plugins."""
|
103
|
+
core_plugins = [
|
104
|
+
"core.filemanager",
|
105
|
+
"core.codeanalyzer",
|
106
|
+
"core.system",
|
107
|
+
"core.imagedisplay",
|
108
|
+
"dev.pythondev",
|
109
|
+
"dev.visualization",
|
110
|
+
"ui.userinterface",
|
111
|
+
"web.webtools",
|
112
|
+
]
|
113
|
+
|
114
|
+
available = []
|
115
|
+
for plugin_name in core_plugins:
|
116
|
+
plugin = load_core_plugin(plugin_name)
|
117
|
+
if plugin:
|
118
|
+
available.append(plugin_name)
|
119
|
+
|
120
|
+
return available
|
@@ -0,0 +1,125 @@
|
|
1
|
+
"""
|
2
|
+
Fixed core plugin loader.
|
3
|
+
|
4
|
+
This module provides a working implementation to load core plugins
|
5
|
+
by directly using the Plugin base class properly.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import importlib.util
|
9
|
+
import sys
|
10
|
+
from pathlib import Path
|
11
|
+
from typing import Optional, List, Type
|
12
|
+
|
13
|
+
from janito.plugins.base import Plugin, PluginMetadata
|
14
|
+
from janito.tools.function_adapter import create_function_tool
|
15
|
+
from janito.tools.tool_base import ToolBase
|
16
|
+
|
17
|
+
|
18
|
+
class CorePlugin(Plugin):
|
19
|
+
"""Working core plugin implementation."""
|
20
|
+
|
21
|
+
def __init__(self, name: str, description: str, tools: list):
|
22
|
+
self._plugin_name = name
|
23
|
+
self._description = description
|
24
|
+
self._tools = tools
|
25
|
+
self._tool_classes = []
|
26
|
+
super().__init__() # Call super after setting attributes
|
27
|
+
|
28
|
+
def get_metadata(self) -> PluginMetadata:
|
29
|
+
return PluginMetadata(
|
30
|
+
name=self._plugin_name,
|
31
|
+
version="1.0.0",
|
32
|
+
description=self._description,
|
33
|
+
author="Janito",
|
34
|
+
license="MIT",
|
35
|
+
)
|
36
|
+
|
37
|
+
def get_tools(self) -> List[Type[ToolBase]]:
|
38
|
+
return self._tool_classes
|
39
|
+
|
40
|
+
def initialize(self):
|
41
|
+
"""Initialize by creating tool classes."""
|
42
|
+
self._tool_classes = []
|
43
|
+
for tool_func in self._tools:
|
44
|
+
if callable(tool_func):
|
45
|
+
tool_class = create_function_tool(tool_func)
|
46
|
+
self._tool_classes.append(tool_class)
|
47
|
+
|
48
|
+
|
49
|
+
def load_core_plugin(plugin_name: str) -> Optional[Plugin]:
|
50
|
+
"""
|
51
|
+
Load a core plugin by name.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
plugin_name: Name of the plugin (e.g., 'core.filemanager')
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
Plugin instance if loaded successfully
|
58
|
+
"""
|
59
|
+
try:
|
60
|
+
# Parse plugin name
|
61
|
+
if "." not in plugin_name:
|
62
|
+
return None
|
63
|
+
|
64
|
+
parts = plugin_name.split(".")
|
65
|
+
if len(parts) != 2:
|
66
|
+
return None
|
67
|
+
|
68
|
+
package_name, submodule_name = parts
|
69
|
+
|
70
|
+
# Handle imagedisplay specially
|
71
|
+
if plugin_name == "core.imagedisplay":
|
72
|
+
# Import the actual plugin class
|
73
|
+
try:
|
74
|
+
from plugins.core.imagedisplay.plugin import ImageDisplayPlugin
|
75
|
+
return ImageDisplayPlugin()
|
76
|
+
except ImportError:
|
77
|
+
# If import fails, return None - don't return True
|
78
|
+
return None
|
79
|
+
|
80
|
+
# Build path to plugin
|
81
|
+
plugin_path = Path("plugins") / package_name / submodule_name / "__init__.py"
|
82
|
+
if not plugin_path.exists():
|
83
|
+
return None
|
84
|
+
|
85
|
+
# Load the module
|
86
|
+
spec = importlib.util.spec_from_file_location(plugin_name, plugin_path)
|
87
|
+
if spec is None or spec.loader is None:
|
88
|
+
return None
|
89
|
+
|
90
|
+
module = importlib.util.module_from_spec(spec)
|
91
|
+
spec.loader.exec_module(module)
|
92
|
+
|
93
|
+
# Get plugin info
|
94
|
+
name = getattr(module, "__plugin_name__", plugin_name)
|
95
|
+
description = getattr(module, "__plugin_description__", f"Core plugin: {plugin_name}")
|
96
|
+
tools = getattr(module, "__plugin_tools__", [])
|
97
|
+
|
98
|
+
if not tools:
|
99
|
+
return None
|
100
|
+
|
101
|
+
# Create plugin
|
102
|
+
plugin = CorePlugin(name, description, tools)
|
103
|
+
plugin.initialize()
|
104
|
+
return plugin
|
105
|
+
|
106
|
+
except Exception as e:
|
107
|
+
print(f"Error loading core plugin {plugin_name}: {e}")
|
108
|
+
return None
|
109
|
+
|
110
|
+
|
111
|
+
def get_core_plugins() -> list:
|
112
|
+
"""Get list of all available core plugins."""
|
113
|
+
core_plugins = [
|
114
|
+
"core.filemanager",
|
115
|
+
"core.codeanalyzer",
|
116
|
+
"core.system",
|
117
|
+
"core.imagedisplay",
|
118
|
+
"dev.pythondev",
|
119
|
+
"dev.visualization",
|
120
|
+
"ui.userinterface",
|
121
|
+
"web.webtools",
|
122
|
+
]
|
123
|
+
|
124
|
+
# All core plugins are always available
|
125
|
+
return core_plugins
|
janito/plugins/discovery.py
CHANGED
@@ -31,9 +31,9 @@ from pathlib import Path
|
|
31
31
|
from typing import Optional, List
|
32
32
|
import logging
|
33
33
|
|
34
|
-
from
|
34
|
+
from .base import Plugin
|
35
35
|
from .builtin import load_builtin_plugin, BuiltinPluginRegistry
|
36
|
-
from
|
36
|
+
from .core_loader import load_core_plugin
|
37
37
|
|
38
38
|
logger = logging.getLogger(__name__)
|
39
39
|
|
@@ -75,13 +75,13 @@ def discover_plugins(
|
|
75
75
|
parts = plugin_name.split(".")
|
76
76
|
if len(parts) == 2:
|
77
77
|
package_name, submodule_name = parts
|
78
|
-
|
78
|
+
|
79
79
|
# Handle core plugins with dedicated loader
|
80
80
|
if plugin_name.startswith(("core.", "dev.", "ui.", "web.")):
|
81
81
|
plugin = load_core_plugin(plugin_name)
|
82
82
|
if plugin:
|
83
83
|
return plugin
|
84
|
-
|
84
|
+
|
85
85
|
for base_path in all_paths:
|
86
86
|
package_path = base_path / package_name / submodule_name / "__init__.py"
|
87
87
|
if package_path.exists():
|
@@ -157,7 +157,7 @@ def _load_plugin_from_file(
|
|
157
157
|
|
158
158
|
# Check for package-based plugin with __plugin_name__ metadata
|
159
159
|
if hasattr(module, "__plugin_name__"):
|
160
|
-
from janito.
|
160
|
+
from janito.plugins.base import PluginMetadata
|
161
161
|
|
162
162
|
# Create a dynamic plugin class
|
163
163
|
class PackagePlugin(Plugin):
|
janito/plugins/discovery_core.py
CHANGED
@@ -17,11 +17,11 @@ from .core_adapter import CorePluginAdapter
|
|
17
17
|
def _load_core_plugin(package_path: Path, plugin_name: str) -> Optional[Plugin]:
|
18
18
|
"""
|
19
19
|
Load a core plugin from a package directory.
|
20
|
-
|
20
|
+
|
21
21
|
Args:
|
22
22
|
package_path: Path to the __init__.py file
|
23
23
|
plugin_name: Full plugin name (e.g., core.filemanager)
|
24
|
-
|
24
|
+
|
25
25
|
Returns:
|
26
26
|
Plugin instance if loaded successfully
|
27
27
|
"""
|
@@ -30,25 +30,20 @@ def _load_core_plugin(package_path: Path, plugin_name: str) -> Optional[Plugin]:
|
|
30
30
|
spec = importlib.util.spec_from_file_location(plugin_name, package_path)
|
31
31
|
if spec is None or spec.loader is None:
|
32
32
|
return None
|
33
|
-
|
33
|
+
|
34
34
|
module = importlib.util.module_from_spec(spec)
|
35
35
|
spec.loader.exec_module(module)
|
36
|
-
|
36
|
+
|
37
37
|
# Get plugin metadata
|
38
38
|
plugin_name_attr = getattr(module, "__plugin_name__", plugin_name)
|
39
|
-
description = getattr(
|
40
|
-
|
41
|
-
)
|
42
|
-
|
39
|
+
description = getattr(module, "__plugin_description__", f"Core plugin: {plugin_name}")
|
40
|
+
|
43
41
|
# Create and return the core plugin adapter
|
44
42
|
plugin = CorePluginAdapter(plugin_name_attr, description, module)
|
45
43
|
plugin.initialize() # Initialize to set up tools
|
46
44
|
return plugin
|
47
|
-
|
45
|
+
|
48
46
|
except Exception as e:
|
49
47
|
import logging
|
50
|
-
|
51
|
-
|
52
|
-
f"Failed to load core plugin {plugin_name}: {e}"
|
53
|
-
)
|
54
|
-
return None
|
48
|
+
logging.getLogger(__name__).error(f"Failed to load core plugin {plugin_name}: {e}")
|
49
|
+
return None
|
janito/plugins/manager.py
CHANGED
@@ -10,7 +10,7 @@ from pathlib import Path
|
|
10
10
|
from typing import Dict, List, Optional, Any
|
11
11
|
import logging
|
12
12
|
|
13
|
-
from
|
13
|
+
from .base import Plugin, PluginMetadata
|
14
14
|
from .discovery import discover_plugins
|
15
15
|
from .config import load_plugins_config, get_user_plugins_dir
|
16
16
|
from .builtin import BuiltinPluginRegistry, load_builtin_plugin
|
janito/providers/__init__.py
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
from janito.llm.model import LLMModelInfo
|
2
2
|
|
3
3
|
MOONSHOT_MODEL_SPECS = {
|
4
|
-
"kimi-k2-0905": LLMModelInfo(
|
5
|
-
name="kimi-k2-0905",
|
4
|
+
"kimi-k2-0905-preview": LLMModelInfo(
|
5
|
+
name="kimi-k2-0905-preview",
|
6
6
|
context=256000,
|
7
7
|
max_input=200000,
|
8
8
|
max_cot="N/A",
|
9
|
-
max_response=
|
9
|
+
max_response=4096,
|
10
10
|
thinking_supported=False,
|
11
11
|
default_temp=0.2,
|
12
12
|
open="moonshot",
|
13
13
|
driver="OpenAIModelDriver",
|
14
14
|
),
|
15
|
-
"kimi-k2-
|
16
|
-
name="kimi-k2-
|
15
|
+
"kimi-k2-0711-preview": LLMModelInfo(
|
16
|
+
name="kimi-k2-0711-preview",
|
17
17
|
context=128000,
|
18
18
|
max_input=100000,
|
19
19
|
max_cot="N/A",
|
@@ -23,8 +23,8 @@ MOONSHOT_MODEL_SPECS = {
|
|
23
23
|
open="moonshot",
|
24
24
|
driver="OpenAIModelDriver",
|
25
25
|
),
|
26
|
-
"kimi-k2-
|
27
|
-
name="kimi-k2-
|
26
|
+
"kimi-k2-turbo-preview": LLMModelInfo(
|
27
|
+
name="kimi-k2-turbo-preview",
|
28
28
|
context=128000,
|
29
29
|
max_input=100000,
|
30
30
|
max_cot="N/A",
|
@@ -12,7 +12,7 @@ class MoonshotProvider(LLMProvider):
|
|
12
12
|
NAME = "moonshot"
|
13
13
|
MAINTAINER = "João Pinto <janito@ikignosis.org>"
|
14
14
|
MODEL_SPECS = MOONSHOT_MODEL_SPECS
|
15
|
-
DEFAULT_MODEL = "kimi-k2-
|
15
|
+
DEFAULT_MODEL = "kimi-k2-turbo-preview"
|
16
16
|
|
17
17
|
def __init__(
|
18
18
|
self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
|
janito/tools/__init__.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
from janito.tools.adapters.local import
|
2
|
-
|
3
|
-
LocalToolsAdapter
|
1
|
+
from janito.tools.adapters.local import (
|
2
|
+
local_tools_adapter as _internal_local_tools_adapter,
|
3
|
+
LocalToolsAdapter,
|
4
4
|
)
|
5
5
|
|
6
6
|
|
@@ -11,10 +11,8 @@ def get_local_tools_adapter(workdir=None, allowed_permissions=None):
|
|
11
11
|
if workdir is not None and not os.path.exists(workdir):
|
12
12
|
os.makedirs(workdir, exist_ok=True)
|
13
13
|
# Permissions are now managed globally; ignore allowed_permissions argument except for backward compatibility
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
registry = initialize_tools(LocalToolsAdapter(workdir=workdir))
|
14
|
+
# Reuse the singleton adapter defined in janito.tools.adapters.local to maintain tool registrations
|
15
|
+
registry = _internal_local_tools_adapter
|
18
16
|
# Change workdir if requested
|
19
17
|
if workdir is not None:
|
20
18
|
try:
|
@@ -29,42 +27,10 @@ def get_local_tools_adapter(workdir=None, allowed_permissions=None):
|
|
29
27
|
return registry
|
30
28
|
|
31
29
|
|
32
|
-
|
33
|
-
local_tools_adapter = None
|
34
|
-
|
35
|
-
|
36
|
-
def _initialize_global_adapter():
|
37
|
-
"""Initialize the global tools adapter."""
|
38
|
-
global local_tools_adapter
|
39
|
-
if local_tools_adapter is None:
|
40
|
-
from janito.tools.cli_initializer import get_cli_tools_adapter
|
41
|
-
# Try CLI initialization first
|
42
|
-
local_tools_adapter = get_cli_tools_adapter()
|
43
|
-
if local_tools_adapter is None:
|
44
|
-
# Fallback to regular initialization
|
45
|
-
from janito.tools.initialize import initialize_tools
|
46
|
-
local_tools_adapter = initialize_tools(LocalToolsAdapter())
|
47
|
-
|
48
|
-
|
49
|
-
def get_local_tools_adapter(workdir=None, allowed_permissions=None):
|
50
|
-
"""Get the global tools adapter, initializing on first use."""
|
51
|
-
global local_tools_adapter
|
52
|
-
if local_tools_adapter is None:
|
53
|
-
_initialize_global_adapter()
|
54
|
-
|
55
|
-
# Handle workdir if provided
|
56
|
-
if workdir is not None and local_tools_adapter is not None:
|
57
|
-
import os
|
58
|
-
|
59
|
-
if not os.path.exists(workdir):
|
60
|
-
os.makedirs(workdir, exist_ok=True)
|
61
|
-
os.chdir(workdir)
|
62
|
-
local_tools_adapter.workdir = workdir
|
63
|
-
|
64
|
-
return local_tools_adapter
|
65
|
-
|
30
|
+
local_tools_adapter = _internal_local_tools_adapter
|
66
31
|
|
67
32
|
__all__ = [
|
68
33
|
"LocalToolsAdapter",
|
69
34
|
"get_local_tools_adapter",
|
35
|
+
"local_tools_adapter",
|
70
36
|
]
|
@@ -1,6 +1 @@
|
|
1
|
-
|
2
|
-
Tools providers package: for plug-and-play tool collections, integrations, and adapters.
|
3
|
-
|
4
|
-
This package contains the core adapter infrastructure for managing tools,
|
5
|
-
while the actual tool implementations have been moved to the plugins system.
|
6
|
-
"""
|
1
|
+
# Tools providers package: for plug-and-play tool collections, integrations, and adapters.
|
@@ -1,10 +1,73 @@
|
|
1
|
-
|
2
|
-
Local tools adapter for janito.
|
1
|
+
from .adapter import LocalToolsAdapter
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
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 .read_files import ReadFilesTool
|
11
|
+
from .move_file import MoveFileTool
|
12
|
+
from .open_url import OpenUrlTool
|
13
|
+
from .open_html_in_browser import OpenHtmlInBrowserTool
|
14
|
+
from .python_code_run import PythonCodeRunTool
|
15
|
+
from .python_command_run import PythonCommandRunTool
|
16
|
+
from .python_file_run import PythonFileRunTool
|
17
|
+
from .remove_directory import RemoveDirectoryTool
|
18
|
+
from .remove_file import RemoveFileTool
|
19
|
+
from .replace_text_in_file import ReplaceTextInFileTool
|
20
|
+
from .run_bash_command import RunBashCommandTool
|
21
|
+
from .run_powershell_command import RunPowershellCommandTool
|
22
|
+
from .get_file_outline.core import GetFileOutlineTool
|
23
|
+
from .get_file_outline.search_outline import SearchOutlineTool
|
24
|
+
from .search_text.core import SearchTextTool
|
25
|
+
from .validate_file_syntax.core import ValidateFileSyntaxTool
|
26
|
+
from .read_chart import ReadChartTool
|
27
|
+
from .show_image import ShowImageTool
|
28
|
+
from .show_image_grid import ShowImageGridTool
|
7
29
|
|
8
|
-
from .
|
30
|
+
from janito.tools.tool_base import ToolPermissions
|
31
|
+
import os
|
32
|
+
from janito.tools.permissions import get_global_allowed_permissions
|
33
|
+
|
34
|
+
# Singleton tools adapter with all standard tools registered
|
35
|
+
local_tools_adapter = LocalToolsAdapter(workdir=os.getcwd())
|
36
|
+
|
37
|
+
|
38
|
+
def get_local_tools_adapter(workdir=None):
|
39
|
+
return LocalToolsAdapter(workdir=workdir or os.getcwd())
|
40
|
+
|
41
|
+
|
42
|
+
# Register tools
|
43
|
+
for tool_class in [
|
44
|
+
AskUserTool,
|
45
|
+
CopyFileTool,
|
46
|
+
CreateDirectoryTool,
|
47
|
+
CreateFileTool,
|
48
|
+
FetchUrlTool,
|
49
|
+
FindFilesTool,
|
50
|
+
ViewFileTool,
|
51
|
+
ReadFilesTool,
|
52
|
+
MoveFileTool,
|
53
|
+
OpenUrlTool,
|
54
|
+
OpenHtmlInBrowserTool,
|
55
|
+
PythonCodeRunTool,
|
56
|
+
PythonCommandRunTool,
|
57
|
+
PythonFileRunTool,
|
58
|
+
RemoveDirectoryTool,
|
59
|
+
RemoveFileTool,
|
60
|
+
ReplaceTextInFileTool,
|
61
|
+
RunBashCommandTool,
|
62
|
+
RunPowershellCommandTool,
|
63
|
+
GetFileOutlineTool,
|
64
|
+
SearchOutlineTool,
|
65
|
+
SearchTextTool,
|
66
|
+
ValidateFileSyntaxTool,
|
67
|
+
ReadChartTool,
|
68
|
+
ShowImageTool,
|
69
|
+
ShowImageGridTool,
|
70
|
+
]:
|
71
|
+
local_tools_adapter.register_tool(tool_class)
|
9
72
|
|
10
|
-
|
73
|
+
# DEBUG: Print registered tools at startup
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
|
-
from .
|
2
|
+
from janito.tools.adapters.local.adapter import register_local_tool
|
3
3
|
from janito.tools.loop_protection_decorator import protect_against_loops
|
4
4
|
|
5
5
|
from rich import print as rich_print
|
@@ -16,8 +16,8 @@ from prompt_toolkit.styles import Style
|
|
16
16
|
toolbar_style = Style.from_dict({"bottom-toolbar": "fg:yellow bg:darkred"})
|
17
17
|
|
18
18
|
|
19
|
-
@
|
20
|
-
class
|
19
|
+
@register_local_tool
|
20
|
+
class AskUserTool(ToolBase):
|
21
21
|
"""
|
22
22
|
Prompts the user for clarification or input with a question.
|
23
23
|
|
@@ -0,0 +1,87 @@
|
|
1
|
+
import os
|
2
|
+
from janito.tools.path_utils import expand_path
|
3
|
+
import shutil
|
4
|
+
from typing import List, Union
|
5
|
+
from janito.tools.adapters.local.adapter import register_local_tool
|
6
|
+
from janito.tools.tool_base import ToolBase, ToolPermissions
|
7
|
+
from janito.tools.tool_utils import display_path
|
8
|
+
from janito.report_events import ReportAction
|
9
|
+
from janito.i18n import tr
|
10
|
+
|
11
|
+
|
12
|
+
@register_local_tool
|
13
|
+
class CopyFileTool(ToolBase):
|
14
|
+
"""
|
15
|
+
Copy one or more files to a target directory, or copy a single file to a new file.
|
16
|
+
Args:
|
17
|
+
sources (str): Space-separated path(s) to the file(s) to copy.
|
18
|
+
For multiple sources, provide a single string with paths separated by spaces.
|
19
|
+
target (str): Destination path. If copying multiple sources, this must be an existing directory.
|
20
|
+
overwrite (bool, optional): Overwrite existing files. Default: False.
|
21
|
+
Recommended only after reading the file to be overwritten.
|
22
|
+
Returns:
|
23
|
+
str: Status string for each copy operation.
|
24
|
+
"""
|
25
|
+
|
26
|
+
permissions = ToolPermissions(read=True, write=True)
|
27
|
+
tool_name = "copy_file"
|
28
|
+
|
29
|
+
def run(self, sources: str, target: str, overwrite: bool = False) -> str:
|
30
|
+
source_list = [expand_path(src) for src in sources.split() if src]
|
31
|
+
target = expand_path(target)
|
32
|
+
messages = []
|
33
|
+
if len(source_list) > 1:
|
34
|
+
if not os.path.isdir(target):
|
35
|
+
return tr(
|
36
|
+
"❗ Target must be an existing directory when copying multiple files: '{target}'",
|
37
|
+
target=display_path(target),
|
38
|
+
)
|
39
|
+
for src in source_list:
|
40
|
+
if not os.path.isfile(src):
|
41
|
+
messages.append(
|
42
|
+
tr(
|
43
|
+
"❗ Source file does not exist: '{src}'",
|
44
|
+
src=display_path(src),
|
45
|
+
)
|
46
|
+
)
|
47
|
+
continue
|
48
|
+
dst = os.path.join(target, os.path.basename(src))
|
49
|
+
messages.append(self._copy_one(src, dst, overwrite=overwrite))
|
50
|
+
else:
|
51
|
+
src = source_list[0]
|
52
|
+
if os.path.isdir(target):
|
53
|
+
dst = os.path.join(target, os.path.basename(src))
|
54
|
+
else:
|
55
|
+
dst = target
|
56
|
+
messages.append(self._copy_one(src, dst, overwrite=overwrite))
|
57
|
+
return "\n".join(messages)
|
58
|
+
|
59
|
+
def _copy_one(self, src, dst, overwrite=False) -> str:
|
60
|
+
disp_src = display_path(src)
|
61
|
+
disp_dst = display_path(dst)
|
62
|
+
if not os.path.isfile(src):
|
63
|
+
return tr("❗ Source file does not exist: '{src}'", src=disp_src)
|
64
|
+
if os.path.exists(dst) and not overwrite:
|
65
|
+
return tr(
|
66
|
+
"❗ Target already exists: '{dst}'. Set overwrite=True to replace.",
|
67
|
+
dst=disp_dst,
|
68
|
+
)
|
69
|
+
try:
|
70
|
+
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
71
|
+
shutil.copy2(src, dst)
|
72
|
+
note = (
|
73
|
+
"\n⚠️ Overwrote existing file. (recommended only after reading the file to be overwritten)"
|
74
|
+
if (os.path.exists(dst) and overwrite)
|
75
|
+
else ""
|
76
|
+
)
|
77
|
+
self.report_success(
|
78
|
+
tr("✅ Copied '{src}' to '{dst}'", src=disp_src, dst=disp_dst)
|
79
|
+
)
|
80
|
+
return tr("✅ Copied '{src}' to '{dst}'", src=disp_src, dst=disp_dst) + note
|
81
|
+
except Exception as e:
|
82
|
+
return tr(
|
83
|
+
"❗ Copy failed from '{src}' to '{dst}': {err}",
|
84
|
+
src=disp_src,
|
85
|
+
dst=disp_dst,
|
86
|
+
err=str(e),
|
87
|
+
)
|