janito 3.8.0__py3-none-any.whl → 3.10.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/agent_events.py +75 -0
- janito/cli/chat_mode/session.py +1 -0
- janito/cli/chat_mode/shell/commands/__init__.py +2 -0
- janito/cli/chat_mode/shell/commands/interactive.py +33 -0
- janito/cli/chat_mode/toolbar.py +16 -1
- janito/cli/cli_commands/list_tools.py +1 -1
- janito/cli/core/runner.py +33 -0
- janito/cli/main_cli.py +9 -0
- janito/cli/prompt_core.py +301 -257
- janito/cli/rich_terminal_reporter.py +170 -171
- janito/cli/single_shot_mode/handler.py +19 -0
- janito/llm/agent.py +65 -0
- janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/core.py +7 -2
- janito/plugins/core/filemanager/tools/validate_file_syntax/txt_validator.py +28 -0
- janito/plugins/manager.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/__init__.py +7 -0
- janito/{tools/adapters → plugins/tools}/local/adapter.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/ask_user.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/copy_file.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/create_directory.py +45 -2
- janito/{tools/adapters → plugins/tools}/local/create_file.py +10 -6
- janito/{tools/adapters → plugins/tools}/local/delete_text_in_file.py +2 -2
- janito/{tools/adapters → plugins/tools}/local/fetch_url.py +3 -3
- janito/{tools/adapters → plugins/tools}/local/find_files.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/get_file_outline/core.py +2 -2
- janito/{tools/adapters → plugins/tools}/local/move_file.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/open_html_in_browser.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/open_url.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/python_code_run.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/python_command_run.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/python_file_run.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/read_chart.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/read_files.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/remove_directory.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/remove_file.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/replace_text_in_file.py +2 -2
- janito/{tools/adapters → plugins/tools}/local/run_bash_command.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/run_powershell_command.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/search_text/core.py +2 -2
- janito/{tools/adapters → plugins/tools}/local/show_image.py +1 -1
- janito/{tools/adapters → plugins/tools}/local/show_image_grid.py +1 -1
- janito/plugins/tools/local/validate_file_syntax/__init__.py +1 -0
- janito/plugins/tools/local/validate_file_syntax/core.py +119 -0
- janito/plugins/tools/local/validate_file_syntax/txt_validator.py +28 -0
- janito/{tools/adapters → plugins/tools}/local/view_file.py +1 -1
- janito/tests/test_tool_adapter_case_insensitive.py +112 -0
- janito/tools/__init__.py +2 -2
- janito/tools/inspect_registry.py +1 -1
- janito/tools/tool_base.py +8 -1
- janito/tools/tools_adapter.py +514 -510
- {janito-3.8.0.dist-info → janito-3.10.0.dist-info}/METADATA +84 -84
- {janito-3.8.0.dist-info → janito-3.10.0.dist-info}/RECORD +77 -70
- /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/__init__.py +0 -0
- /janito/{tools/adapters → plugins/tools}/__init__.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/get_file_outline/__init__.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/get_file_outline/java_outline.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/get_file_outline/markdown_outline.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/get_file_outline/python_outline.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/get_file_outline/search_outline.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/search_text/__init__.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/search_text/match_lines.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/search_text/pattern_utils.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/search_text/traverse_directory.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/css_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/html_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/jinja2_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/js_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/json_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/markdown_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/ps1_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/python_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/xml_validator.py +0 -0
- /janito/{tools/adapters → plugins/tools}/local/validate_file_syntax/yaml_validator.py +0 -0
- {janito-3.8.0.dist-info → janito-3.10.0.dist-info}/WHEEL +0 -0
- {janito-3.8.0.dist-info → janito-3.10.0.dist-info}/entry_points.txt +0 -0
- {janito-3.8.0.dist-info → janito-3.10.0.dist-info}/licenses/LICENSE +0 -0
- {janito-3.8.0.dist-info → janito-3.10.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
from janito.tools.
|
1
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
2
2
|
|
3
3
|
from janito.tools.tool_utils import display_path
|
4
4
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
@@ -6,6 +6,7 @@ from janito.report_events import ReportAction
|
|
6
6
|
from janito.i18n import tr
|
7
7
|
import os
|
8
8
|
from janito.tools.path_utils import expand_path
|
9
|
+
from pathlib import Path
|
9
10
|
|
10
11
|
|
11
12
|
@register_local_tool
|
@@ -43,6 +44,8 @@ class CreateDirectoryTool(ToolBase):
|
|
43
44
|
"❌ Path '{disp_path}' exists and is not a directory.",
|
44
45
|
disp_path=disp_path,
|
45
46
|
)
|
47
|
+
# Generate content summary
|
48
|
+
content_summary = self._get_directory_summary(path)
|
46
49
|
self.report_error(
|
47
50
|
tr(
|
48
51
|
"❗ Directory '{disp_path}' already exists.",
|
@@ -50,8 +53,9 @@ class CreateDirectoryTool(ToolBase):
|
|
50
53
|
)
|
51
54
|
)
|
52
55
|
return tr(
|
53
|
-
"❗ Cannot create directory: '{disp_path}' already exists
|
56
|
+
"❗ Cannot create directory: '{disp_path}' already exists.\n{summary}",
|
54
57
|
disp_path=disp_path,
|
58
|
+
summary=content_summary,
|
55
59
|
)
|
56
60
|
os.makedirs(path, exist_ok=True)
|
57
61
|
self.report_success(tr("✅ Directory created"))
|
@@ -68,3 +72,42 @@ class CreateDirectoryTool(ToolBase):
|
|
68
72
|
)
|
69
73
|
)
|
70
74
|
return tr("❌ Cannot create directory: {error}", error=e)
|
75
|
+
|
76
|
+
def _get_directory_summary(self, path: str) -> str:
|
77
|
+
"""Generate a summary of directory contents."""
|
78
|
+
try:
|
79
|
+
path_obj = Path(path)
|
80
|
+
if not path_obj.exists() or not path_obj.is_dir():
|
81
|
+
return ""
|
82
|
+
|
83
|
+
items = list(path_obj.iterdir())
|
84
|
+
if not items:
|
85
|
+
return "Directory is empty."
|
86
|
+
|
87
|
+
# Count files and directories
|
88
|
+
file_count = sum(1 for item in items if item.is_file())
|
89
|
+
dir_count = sum(1 for item in items if item.is_dir())
|
90
|
+
|
91
|
+
summary_parts = []
|
92
|
+
if file_count > 0:
|
93
|
+
summary_parts.append(f"{file_count} file{'s' if file_count != 1 else ''}")
|
94
|
+
if dir_count > 0:
|
95
|
+
summary_parts.append(f"{dir_count} subdirector{'y' if dir_count == 1 else 'ies'}")
|
96
|
+
|
97
|
+
# Show first few items as examples
|
98
|
+
examples = []
|
99
|
+
for item in sorted(items)[:3]: # Show up to 3 items
|
100
|
+
if item.is_dir():
|
101
|
+
examples.append(f"📁 {item.name}")
|
102
|
+
else:
|
103
|
+
examples.append(f"📄 {item.name}")
|
104
|
+
|
105
|
+
result = f"Contains: {', '.join(summary_parts)}."
|
106
|
+
if examples:
|
107
|
+
result += f"\nExamples: {', '.join(examples)}"
|
108
|
+
if len(items) > 3:
|
109
|
+
result += f" (and {len(items) - 3} more)"
|
110
|
+
|
111
|
+
return result
|
112
|
+
except Exception:
|
113
|
+
return "Unable to read directory contents."
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
from janito.tools.path_utils import expand_path
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
|
5
5
|
from janito.tools.tool_utils import display_path
|
6
6
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
@@ -8,7 +8,7 @@ from janito.report_events import ReportAction
|
|
8
8
|
from janito.i18n import tr
|
9
9
|
from janito.tools.loop_protection_decorator import protect_against_loops
|
10
10
|
|
11
|
-
from janito.tools.
|
11
|
+
from janito.plugins.tools.local.validate_file_syntax.core import validate_file_syntax
|
12
12
|
|
13
13
|
|
14
14
|
@register_local_tool
|
@@ -30,12 +30,12 @@ class CreateFileTool(ToolBase):
|
|
30
30
|
- Cross-platform path handling (Windows, macOS, Linux)
|
31
31
|
|
32
32
|
Args:
|
33
|
-
path (str): Target file path. Supports relative and absolute paths, with automatic
|
33
|
+
path (str, required): Target file path. Supports relative and absolute paths, with automatic
|
34
34
|
expansion of user home directory (~) and environment variables.
|
35
35
|
Examples: "src/main.py", "~/Documents/config.json", "$HOME/.env"
|
36
|
-
content (str): File content to write. Empty string creates empty file.
|
36
|
+
content (str, optional): File content to write. Empty string creates empty file.
|
37
37
|
Supports any text content including Unicode characters, newlines,
|
38
|
-
and binary-safe text representation.
|
38
|
+
and binary-safe text representation. Default: "" (empty file)
|
39
39
|
overwrite (bool, optional): If True, allows overwriting existing files. Default: False.
|
40
40
|
When False, prevents accidental overwrites by checking
|
41
41
|
file existence and showing current content. Always review
|
@@ -71,6 +71,10 @@ class CreateFileTool(ToolBase):
|
|
71
71
|
✅ Created file 2 lines.
|
72
72
|
✅ Syntax OK
|
73
73
|
|
74
|
+
Creating empty file:
|
75
|
+
>>> create_file("empty.txt", "")
|
76
|
+
✅ Created file 0 lines.
|
77
|
+
|
74
78
|
Overwrite protection:
|
75
79
|
>>> create_file("existing.txt", "new content")
|
76
80
|
❗ Cannot create file: file already exists at 'existing.txt'.
|
@@ -85,7 +89,7 @@ class CreateFileTool(ToolBase):
|
|
85
89
|
tool_name = "create_file"
|
86
90
|
|
87
91
|
@protect_against_loops(max_calls=5, time_window=10.0, key_field="path")
|
88
|
-
def run(self, path: str, content: str, overwrite: bool = False) -> str:
|
92
|
+
def run(self, path: str, content: str = "", overwrite: bool = False) -> str:
|
89
93
|
path = expand_path(path)
|
90
94
|
disp_path = display_path(path)
|
91
95
|
if os.path.exists(path) and not overwrite:
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.i18n import tr
|
5
5
|
import shutil
|
6
|
-
from janito.tools.
|
6
|
+
from janito.plugins.tools.local.validate_file_syntax.core import validate_file_syntax
|
7
7
|
|
8
8
|
|
9
9
|
@register_local_tool
|
@@ -5,7 +5,7 @@ import json
|
|
5
5
|
from pathlib import Path
|
6
6
|
from bs4 import BeautifulSoup
|
7
7
|
from typing import Dict, Any, Optional
|
8
|
-
from janito.tools.
|
8
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
9
9
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
10
10
|
from janito.report_events import ReportAction
|
11
11
|
from janito.i18n import tr
|
@@ -33,7 +33,7 @@ class FetchUrlTool(ToolBase):
|
|
33
33
|
|
34
34
|
**Error Cache Behavior:**
|
35
35
|
- HTTP 403 errors: Cached for 24 hours (more permanent)
|
36
|
-
- HTTP 404 errors: Cached for 1 hour (
|
36
|
+
- HTTP 404 errors: Cached for 1 hour (shorter duration)
|
37
37
|
- Other 4xx errors: Cached for 30 minutes
|
38
38
|
- 5xx errors: Not cached (retried on each request)
|
39
39
|
|
@@ -151,7 +151,7 @@ class FetchUrlTool(ToolBase):
|
|
151
151
|
# Cache 403 errors for 24 hours (more permanent)
|
152
152
|
expiration_time = 24 * 3600
|
153
153
|
elif entry["status_code"] == 404:
|
154
|
-
# Cache 404 errors for 1 hour (
|
154
|
+
# Cache 404 errors for 1 hour (shorter duration)
|
155
155
|
expiration_time = 3600
|
156
156
|
else:
|
157
157
|
# Cache other 4xx errors for 30 minutes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.tools.tool_utils import pluralize, display_path
|
5
5
|
from janito.dir_walk_utils import walk_dir_with_gitignore
|
6
6
|
from janito.i18n import tr
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from janito.tools.
|
1
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
2
2
|
from .python_outline import parse_python_outline
|
3
3
|
from .markdown_outline import parse_markdown_outline
|
4
4
|
from janito.formatting import OutlineFormatter
|
@@ -10,7 +10,7 @@ from janito.report_events import ReportAction
|
|
10
10
|
from janito.tools.tool_utils import display_path, pluralize
|
11
11
|
from janito.i18n import tr
|
12
12
|
|
13
|
-
from janito.tools.
|
13
|
+
from janito.plugins.tools.local.adapter import register_local_tool as register_tool
|
14
14
|
from janito.tools.loop_protection_decorator import protect_against_loops
|
15
15
|
|
16
16
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import os
|
2
2
|
from janito.tools.path_utils import expand_path
|
3
3
|
import shutil
|
4
|
-
from janito.tools.
|
4
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
5
5
|
from janito.tools.tool_utils import display_path
|
6
6
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
7
7
|
from janito.report_events import ReportAction
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
import webbrowser
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
5
5
|
from janito.report_events import ReportAction
|
6
6
|
from janito.i18n import tr
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import webbrowser
|
2
|
-
from janito.tools.
|
2
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
3
3
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
4
4
|
from janito.report_events import ReportAction
|
5
5
|
from janito.i18n import tr
|
@@ -5,7 +5,7 @@ import tempfile
|
|
5
5
|
import threading
|
6
6
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
7
7
|
from janito.report_events import ReportAction
|
8
|
-
from janito.tools.
|
8
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
9
9
|
from janito.i18n import tr
|
10
10
|
|
11
11
|
|
@@ -5,7 +5,7 @@ import tempfile
|
|
5
5
|
import threading
|
6
6
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
7
7
|
from janito.report_events import ReportAction
|
8
|
-
from janito.tools.
|
8
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
9
9
|
from janito.i18n import tr
|
10
10
|
|
11
11
|
|
@@ -5,7 +5,7 @@ import tempfile
|
|
5
5
|
import threading
|
6
6
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
7
7
|
from janito.report_events import ReportAction
|
8
|
-
from janito.tools.
|
8
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
9
9
|
from janito.i18n import tr
|
10
10
|
|
11
11
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.tools.tool_utils import display_path
|
5
5
|
from janito.i18n import tr
|
6
6
|
import json
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.tools.tool_utils import pluralize
|
5
5
|
from janito.i18n import tr
|
6
6
|
from janito.tools.loop_protection_decorator import protect_against_loops
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.tools.tool_utils import pluralize, display_path
|
5
5
|
from janito.i18n import tr
|
6
6
|
import shutil
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import os
|
2
2
|
from janito.tools.path_utils import expand_path
|
3
3
|
import shutil
|
4
|
-
from janito.tools.
|
4
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
5
5
|
|
6
6
|
from janito.tools.tool_utils import display_path
|
7
7
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
@@ -1,10 +1,10 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.i18n import tr
|
5
5
|
import shutil
|
6
6
|
import re
|
7
|
-
from janito.tools.
|
7
|
+
from janito.plugins.tools.local.validate_file_syntax.core import validate_file_syntax
|
8
8
|
|
9
9
|
|
10
10
|
@register_local_tool
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.i18n import tr
|
5
5
|
import subprocess
|
6
6
|
import tempfile
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.i18n import tr
|
5
5
|
import subprocess
|
6
6
|
import os
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.tools.tool_utils import pluralize, display_path
|
5
5
|
from janito.i18n import tr
|
6
6
|
import os
|
@@ -11,7 +11,7 @@ from .traverse_directory import traverse_directory
|
|
11
11
|
from janito.tools.loop_protection_decorator import protect_against_loops
|
12
12
|
|
13
13
|
|
14
|
-
from janito.tools.
|
14
|
+
from janito.plugins.tools.local.adapter import register_local_tool as register_tool
|
15
15
|
|
16
16
|
|
17
17
|
@register_tool
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.i18n import tr
|
5
5
|
from janito.tools.loop_protection_decorator import protect_against_loops
|
6
6
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.i18n import tr
|
5
5
|
from janito.tools.loop_protection_decorator import protect_against_loops
|
6
6
|
from typing import Sequence
|
@@ -0,0 +1 @@
|
|
1
|
+
# Validation syntax package
|
@@ -0,0 +1,119 @@
|
|
1
|
+
import os
|
2
|
+
from janito.tools.path_utils import expand_path
|
3
|
+
from janito.i18n import tr
|
4
|
+
from janito.tools.tool_base import ToolBase, ToolPermissions
|
5
|
+
from janito.report_events import ReportAction
|
6
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
7
|
+
from janito.tools.tool_utils import display_path
|
8
|
+
from janito.plugins.tools.local.adapter import register_local_tool as register_tool
|
9
|
+
|
10
|
+
from .python_validator import validate_python
|
11
|
+
from .json_validator import validate_json
|
12
|
+
from .yaml_validator import validate_yaml
|
13
|
+
from .ps1_validator import validate_ps1
|
14
|
+
from .xml_validator import validate_xml
|
15
|
+
from .html_validator import validate_html
|
16
|
+
from .markdown_validator import validate_markdown
|
17
|
+
from .js_validator import validate_js
|
18
|
+
from .css_validator import validate_css
|
19
|
+
from .jinja2_validator import validate_jinja2
|
20
|
+
from .txt_validator import validate_txt
|
21
|
+
from janito.tools.loop_protection_decorator import protect_against_loops
|
22
|
+
|
23
|
+
|
24
|
+
def _get_validator(ext):
|
25
|
+
"""Return the appropriate validator function for the file extension."""
|
26
|
+
mapping = {
|
27
|
+
".py": validate_python,
|
28
|
+
".pyw": validate_python,
|
29
|
+
".json": validate_json,
|
30
|
+
".yml": validate_yaml,
|
31
|
+
".yaml": validate_yaml,
|
32
|
+
".ps1": validate_ps1,
|
33
|
+
".xml": validate_xml,
|
34
|
+
".html": validate_html,
|
35
|
+
".htm": validate_html,
|
36
|
+
".md": validate_markdown,
|
37
|
+
".js": validate_js,
|
38
|
+
".css": validate_css,
|
39
|
+
".j2": validate_jinja2,
|
40
|
+
".jinja2": validate_jinja2,
|
41
|
+
".txt": validate_txt,
|
42
|
+
".text": validate_txt,
|
43
|
+
}
|
44
|
+
return mapping.get(ext)
|
45
|
+
|
46
|
+
|
47
|
+
def _handle_validation_error(e, report_warning):
|
48
|
+
msg = tr("⚠️ Warning: Syntax error: {error}", error=e)
|
49
|
+
if report_warning:
|
50
|
+
report_warning(msg)
|
51
|
+
return msg
|
52
|
+
|
53
|
+
|
54
|
+
def validate_file_syntax(
|
55
|
+
path: str, report_info=None, report_warning=None, report_success=None
|
56
|
+
) -> str:
|
57
|
+
ext = os.path.splitext(path)[1].lower()
|
58
|
+
validator = _get_validator(ext)
|
59
|
+
try:
|
60
|
+
if validator:
|
61
|
+
return validator(path)
|
62
|
+
else:
|
63
|
+
msg = tr("⚠️ Warning: Unsupported file extension: {ext}", ext=ext)
|
64
|
+
if report_warning:
|
65
|
+
report_warning(msg)
|
66
|
+
return msg
|
67
|
+
except Exception as e:
|
68
|
+
return _handle_validation_error(e, report_warning)
|
69
|
+
|
70
|
+
|
71
|
+
class ValidateFileSyntaxTool(ToolBase):
|
72
|
+
"""
|
73
|
+
Validate a file for syntax issues.
|
74
|
+
|
75
|
+
Supported types:
|
76
|
+
- Python (.py, .pyw)
|
77
|
+
- JSON (.json)
|
78
|
+
- YAML (.yml, .yaml)
|
79
|
+
- PowerShell (.ps1)
|
80
|
+
- XML (.xml)
|
81
|
+
- HTML (.html, .htm) [lxml]
|
82
|
+
- Markdown (.md)
|
83
|
+
- JavaScript (.js)
|
84
|
+
- Jinja2 templates (.j2, .jinja2)
|
85
|
+
- Text files (.txt, .text) [UTF-8 validation]
|
86
|
+
|
87
|
+
Args:
|
88
|
+
path (str): Path to the file to validate.
|
89
|
+
Returns:
|
90
|
+
str: Validation status message. Example:
|
91
|
+
- "✅ Syntax OK"
|
92
|
+
- "⚠️ Warning: Syntax error: <error message>"
|
93
|
+
- "⚠️ Warning: UTF-8 decoding error: <error details>"
|
94
|
+
- "⚠️ Warning: Unsupported file extension: <ext>"
|
95
|
+
"""
|
96
|
+
|
97
|
+
permissions = ToolPermissions(read=True)
|
98
|
+
tool_name = "validate_file_syntax"
|
99
|
+
|
100
|
+
@protect_against_loops(max_calls=5, time_window=10.0, key_field="path")
|
101
|
+
def run(self, path: str) -> str:
|
102
|
+
path = expand_path(path)
|
103
|
+
disp_path = display_path(path)
|
104
|
+
self.report_action(
|
105
|
+
tr(
|
106
|
+
"🔎 Validate syntax for file '{disp_path}' ...",
|
107
|
+
disp_path=disp_path,
|
108
|
+
),
|
109
|
+
ReportAction.READ,
|
110
|
+
)
|
111
|
+
result = validate_file_syntax(
|
112
|
+
path,
|
113
|
+
report_warning=self.report_warning,
|
114
|
+
report_success=self.report_success,
|
115
|
+
)
|
116
|
+
if result.startswith("✅"):
|
117
|
+
self.report_success(result, ReportAction.READ)
|
118
|
+
|
119
|
+
return result
|
@@ -0,0 +1,28 @@
|
|
1
|
+
"""Text file validator for UTF-8 encoding validation."""
|
2
|
+
|
3
|
+
import codecs
|
4
|
+
from pathlib import Path
|
5
|
+
|
6
|
+
|
7
|
+
def validate_txt(path: str) -> str:
|
8
|
+
"""
|
9
|
+
Validate a text file for UTF-8 encoding issues.
|
10
|
+
|
11
|
+
Args:
|
12
|
+
path (str): Path to the text file to validate
|
13
|
+
|
14
|
+
Returns:
|
15
|
+
str: Validation status message
|
16
|
+
- "✅ Syntax OK" if file is valid UTF-8
|
17
|
+
- "⚠️ Warning: UTF-8 decoding error: <error details>" if invalid
|
18
|
+
"""
|
19
|
+
try:
|
20
|
+
# Try to read the file with UTF-8 encoding
|
21
|
+
with codecs.open(path, 'r', encoding='utf-8') as f:
|
22
|
+
# Read the entire file to trigger any decoding errors
|
23
|
+
f.read()
|
24
|
+
return "✅ Syntax OK"
|
25
|
+
except UnicodeDecodeError as e:
|
26
|
+
return f"⚠️ Warning: UTF-8 decoding error: {e}"
|
27
|
+
except Exception as e:
|
28
|
+
return f"⚠️ Warning: File read error: {e}"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
2
|
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
4
4
|
from janito.tools.tool_utils import pluralize
|
5
5
|
from janito.i18n import tr
|
6
6
|
from janito.tools.loop_protection_decorator import protect_against_loops
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""Test script to verify tool adapter converts argument names to lowercase."""
|
3
|
+
|
4
|
+
import tempfile
|
5
|
+
import os
|
6
|
+
import subprocess
|
7
|
+
import sys
|
8
|
+
from pathlib import Path
|
9
|
+
import json
|
10
|
+
|
11
|
+
|
12
|
+
def test_tool_adapter_lowercase_conversion():
|
13
|
+
"""Test that tool adapter converts argument names to lowercase."""
|
14
|
+
print("Testing tool adapter lowercase conversion...")
|
15
|
+
|
16
|
+
# Create a simple test tool that logs its arguments
|
17
|
+
test_tool_content = '''
|
18
|
+
from janito.plugins.tools.local.adapter import register_local_tool
|
19
|
+
from janito.tools.tool_base import ToolBase, ToolPermissions
|
20
|
+
|
21
|
+
class TestArgsTool(ToolBase):
|
22
|
+
tool_name = "test_args_tool"
|
23
|
+
description = "Test tool to verify argument case conversion"
|
24
|
+
permissions = ToolPermissions(read=True, write=False, execute=False)
|
25
|
+
|
26
|
+
def execute(self, test_path: str, test_mode: str = "default") -> str:
|
27
|
+
"""Test tool that returns its arguments."""
|
28
|
+
return f"Received: test_path={test_path}, test_mode={test_mode}"
|
29
|
+
|
30
|
+
register_local_tool(TestArgsTool)
|
31
|
+
'''
|
32
|
+
|
33
|
+
# Create a temporary Python file with the test tool
|
34
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
35
|
+
f.write(test_tool_content)
|
36
|
+
test_tool_file = f.name
|
37
|
+
|
38
|
+
try:
|
39
|
+
# Test with mixed case arguments
|
40
|
+
print("\n1. Testing mixed case argument names...")
|
41
|
+
|
42
|
+
# Create a simple test script that uses the tool adapter directly
|
43
|
+
test_script = f'''
|
44
|
+
import sys
|
45
|
+
import os
|
46
|
+
sys.path.insert(0, os.path.join(os.getcwd(), "janito"))
|
47
|
+
|
48
|
+
# Import the test tool to register it
|
49
|
+
exec(open("{test_tool_file}").read())
|
50
|
+
|
51
|
+
from janito.plugins.tools.local.adapter import LocalToolsAdapter
|
52
|
+
from janito.llm.message_parts import FunctionCallMessagePart
|
53
|
+
import json
|
54
|
+
|
55
|
+
# Create a mock function object with mixed case arguments
|
56
|
+
class MockFunction:
|
57
|
+
def __init__(self, name, arguments):
|
58
|
+
self.name = name
|
59
|
+
self.arguments = arguments
|
60
|
+
|
61
|
+
# Create adapter
|
62
|
+
adapter = LocalToolsAdapter()
|
63
|
+
|
64
|
+
# Test with mixed case arguments
|
65
|
+
mixed_case_args = {{"Test_Path": "/tmp/test", "Test_Mode": "verify"}}
|
66
|
+
function = MockFunction("test_args_tool", json.dumps(mixed_case_args))
|
67
|
+
message_part = FunctionCallMessagePart(tool_call_id="test_123", function=function)
|
68
|
+
|
69
|
+
# Execute and print result
|
70
|
+
result = adapter.execute_function_call_message_part(message_part)
|
71
|
+
print(f"Result: {{result}}")
|
72
|
+
'''
|
73
|
+
|
74
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
75
|
+
f.write(test_script)
|
76
|
+
test_script_file = f.name
|
77
|
+
|
78
|
+
try:
|
79
|
+
# Run the test script
|
80
|
+
result = subprocess.run(
|
81
|
+
[sys.executable, test_script_file],
|
82
|
+
capture_output=True,
|
83
|
+
text=True,
|
84
|
+
cwd="/home/janito/janito"
|
85
|
+
)
|
86
|
+
|
87
|
+
print(f"Script output: {result.stdout}")
|
88
|
+
print(f"Script stderr: {result.stderr}")
|
89
|
+
|
90
|
+
# Check if the tool was executed successfully
|
91
|
+
if result.returncode == 0 and "Received: test_path=/tmp/test, test_mode=verify" in result.stdout:
|
92
|
+
print("✓ Mixed case arguments were successfully converted to lowercase")
|
93
|
+
return True
|
94
|
+
else:
|
95
|
+
print("✗ Tool execution failed or arguments were not converted properly")
|
96
|
+
return False
|
97
|
+
|
98
|
+
finally:
|
99
|
+
os.unlink(test_script_file)
|
100
|
+
|
101
|
+
finally:
|
102
|
+
os.unlink(test_tool_file)
|
103
|
+
|
104
|
+
|
105
|
+
if __name__ == "__main__":
|
106
|
+
success = test_tool_adapter_lowercase_conversion()
|
107
|
+
if success:
|
108
|
+
print("\n🎉 Test passed!")
|
109
|
+
sys.exit(0)
|
110
|
+
else:
|
111
|
+
print("\n❌ Test failed!")
|
112
|
+
sys.exit(1)
|
janito/tools/__init__.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from janito.tools.
|
1
|
+
from janito.plugins.tools.local import (
|
2
2
|
local_tools_adapter as _internal_local_tools_adapter,
|
3
3
|
LocalToolsAdapter,
|
4
4
|
)
|
@@ -11,7 +11,7 @@ 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
|
-
# Reuse the singleton adapter defined in janito.tools.
|
14
|
+
# Reuse the singleton adapter defined in janito.plugins.tools.local to maintain tool registrations
|
15
15
|
registry = _internal_local_tools_adapter
|
16
16
|
# Change workdir if requested
|
17
17
|
if workdir is not None:
|
janito/tools/inspect_registry.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
def check_tools_registry():
|
2
2
|
# Import and use the singleton tools adapter instance
|
3
|
-
from janito.tools.
|
3
|
+
from janito.plugins.tools.local import local_tools_adapter
|
4
4
|
|
5
5
|
print("Available tool names:", local_tools_adapter.list_tools())
|
6
6
|
print(
|