janito 2.6.1__py3-none-any.whl → 2.8.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 -7
- janito/__main__.py +4 -5
- janito/_version.py +55 -58
- janito/agent/setup_agent.py +308 -241
- janito/agent/templates/profiles/{system_prompt_template_software developer.txt.j2 → system_prompt_template_Developer_with_Python_Tools.txt.j2} +43 -39
- janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +3 -12
- janito/cli/__init__.py +9 -10
- janito/cli/chat_mode/bindings.py +38 -38
- janito/cli/chat_mode/chat_entry.py +21 -23
- janito/cli/chat_mode/prompt_style.py +22 -25
- janito/cli/chat_mode/script_runner.py +158 -154
- janito/cli/chat_mode/session.py +80 -35
- janito/cli/chat_mode/session_profile_select.py +61 -52
- janito/cli/chat_mode/shell/commands/__init__.py +1 -5
- janito/cli/chat_mode/shell/commands/_priv_check.py +1 -0
- janito/cli/chat_mode/shell/commands/bang.py +10 -3
- janito/cli/chat_mode/shell/commands/conversation_restart.py +24 -7
- janito/cli/chat_mode/shell/commands/execute.py +22 -7
- janito/cli/chat_mode/shell/commands/help.py +4 -1
- janito/cli/chat_mode/shell/commands/model.py +13 -5
- janito/cli/chat_mode/shell/commands/privileges.py +21 -0
- janito/cli/chat_mode/shell/commands/prompt.py +0 -2
- janito/cli/chat_mode/shell/commands/read.py +22 -5
- janito/cli/chat_mode/shell/commands/tools.py +15 -4
- janito/cli/chat_mode/shell/commands/write.py +22 -5
- janito/cli/chat_mode/shell/input_history.py +3 -1
- janito/cli/chat_mode/shell/session/manager.py +0 -2
- janito/cli/chat_mode/toolbar.py +25 -19
- janito/cli/cli_commands/list_models.py +1 -1
- janito/cli/cli_commands/list_providers.py +1 -0
- janito/cli/cli_commands/list_tools.py +35 -7
- janito/cli/cli_commands/model_utils.py +5 -3
- janito/cli/cli_commands/show_config.py +12 -0
- janito/cli/cli_commands/show_system_prompt.py +23 -9
- janito/cli/config.py +0 -13
- janito/cli/core/getters.py +2 -0
- janito/cli/core/runner.py +25 -8
- janito/cli/core/setters.py +13 -76
- janito/cli/main_cli.py +9 -25
- janito/cli/prompt_core.py +19 -18
- janito/cli/prompt_setup.py +6 -3
- janito/cli/rich_terminal_reporter.py +19 -5
- janito/cli/single_shot_mode/handler.py +104 -95
- janito/cli/verbose_output.py +5 -1
- janito/config_manager.py +4 -0
- janito/drivers/azure_openai/driver.py +27 -30
- janito/drivers/driver_registry.py +27 -27
- janito/drivers/openai/driver.py +452 -436
- janito/formatting_token.py +12 -4
- janito/llm/agent.py +15 -6
- janito/llm/driver.py +1 -0
- janito/provider_registry.py +139 -178
- janito/providers/__init__.py +2 -0
- janito/providers/anthropic/model_info.py +40 -41
- janito/providers/anthropic/provider.py +75 -80
- janito/providers/azure_openai/provider.py +9 -4
- janito/providers/deepseek/provider.py +5 -4
- janito/providers/google/model_info.py +4 -2
- janito/providers/google/provider.py +11 -5
- janito/providers/groq/__init__.py +1 -0
- janito/providers/groq/model_info.py +46 -0
- janito/providers/groq/provider.py +76 -0
- janito/providers/moonshotai/__init__.py +1 -0
- janito/providers/moonshotai/model_info.py +15 -0
- janito/providers/moonshotai/provider.py +89 -0
- janito/providers/openai/provider.py +6 -7
- janito/tools/__init__.py +2 -0
- janito/tools/adapters/local/__init__.py +67 -66
- janito/tools/adapters/local/adapter.py +21 -4
- janito/tools/adapters/local/ask_user.py +1 -0
- janito/tools/adapters/local/copy_file.py +1 -0
- janito/tools/adapters/local/create_directory.py +1 -0
- janito/tools/adapters/local/create_file.py +1 -0
- janito/tools/adapters/local/delete_text_in_file.py +2 -1
- janito/tools/adapters/local/fetch_url.py +1 -0
- janito/tools/adapters/local/find_files.py +7 -6
- janito/tools/adapters/local/get_file_outline/core.py +1 -0
- janito/tools/adapters/local/get_file_outline/java_outline.py +22 -15
- janito/tools/adapters/local/get_file_outline/search_outline.py +1 -0
- janito/tools/adapters/local/move_file.py +4 -3
- janito/tools/adapters/local/open_html_in_browser.py +15 -5
- janito/tools/adapters/local/open_url.py +1 -0
- janito/tools/adapters/local/python_code_run.py +1 -0
- janito/tools/adapters/local/python_command_run.py +1 -0
- janito/tools/adapters/local/python_file_run.py +1 -0
- janito/tools/adapters/local/read_files.py +55 -40
- janito/tools/adapters/local/remove_directory.py +1 -0
- janito/tools/adapters/local/remove_file.py +1 -0
- janito/tools/adapters/local/replace_text_in_file.py +4 -3
- janito/tools/adapters/local/run_bash_command.py +1 -0
- janito/tools/adapters/local/run_powershell_command.py +1 -0
- janito/tools/adapters/local/search_text/core.py +18 -17
- janito/tools/adapters/local/search_text/match_lines.py +5 -5
- janito/tools/adapters/local/search_text/pattern_utils.py +1 -1
- janito/tools/adapters/local/search_text/traverse_directory.py +7 -7
- janito/tools/adapters/local/validate_file_syntax/core.py +1 -1
- janito/tools/adapters/local/validate_file_syntax/html_validator.py +8 -1
- janito/tools/disabled_tools.py +68 -0
- janito/tools/path_security.py +18 -11
- janito/tools/permissions.py +6 -0
- janito/tools/permissions_parse.py +4 -3
- janito/tools/tool_base.py +11 -5
- janito/tools/tool_use_tracker.py +1 -4
- janito/tools/tool_utils.py +1 -1
- janito/tools/tools_adapter.py +57 -25
- {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/METADATA +411 -417
- janito-2.8.0.dist-info/RECORD +202 -0
- janito/cli/chat_mode/shell/commands/livelogs.py +0 -49
- janito/drivers/mistralai/driver.py +0 -41
- janito/providers/mistralai/model_info.py +0 -37
- janito/providers/mistralai/provider.py +0 -72
- janito/providers/provider_static_info.py +0 -18
- janito-2.6.1.dist-info/RECORD +0 -199
- /janito/agent/templates/profiles/{system_prompt_template_assistant.txt.j2 → system_prompt_template_model_conversation_without_tools_or_context.txt.j2} +0 -0
- {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/WHEEL +0 -0
- {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/entry_points.txt +0 -0
- {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/licenses/LICENSE +0 -0
- {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/top_level.txt +0 -0
janito/tools/tools_adapter.py
CHANGED
@@ -3,6 +3,7 @@ from janito.tools.tool_events import ToolCallStarted, ToolCallFinished, ToolCall
|
|
3
3
|
from janito.exceptions import ToolCallException
|
4
4
|
from janito.tools.tool_base import ToolPermissions
|
5
5
|
|
6
|
+
|
6
7
|
class ToolsAdapterBase:
|
7
8
|
"""
|
8
9
|
Composable entry point for tools management and provisioning in LLM pipelines.
|
@@ -11,9 +12,7 @@ class ToolsAdapterBase:
|
|
11
12
|
After refactor, also responsible for tool execution.
|
12
13
|
"""
|
13
14
|
|
14
|
-
def __init__(
|
15
|
-
self, tools=None, event_bus=None
|
16
|
-
):
|
15
|
+
def __init__(self, tools=None, event_bus=None):
|
17
16
|
self._tools = tools or []
|
18
17
|
self._event_bus = event_bus # event bus can be set on all adapters
|
19
18
|
self.verbose_tools = False
|
@@ -32,31 +31,43 @@ class ToolsAdapterBase:
|
|
32
31
|
def is_tool_allowed(self, tool):
|
33
32
|
"""Check if a tool is allowed based on current global AllowedPermissionsState."""
|
34
33
|
from janito.tools.permissions import get_global_allowed_permissions
|
34
|
+
|
35
35
|
allowed_permissions = get_global_allowed_permissions()
|
36
36
|
perms = tool.permissions # permissions are mandatory and type-checked
|
37
37
|
# If all permissions are False, block all tools
|
38
|
-
if not (
|
38
|
+
if not (
|
39
|
+
allowed_permissions.read
|
40
|
+
or allowed_permissions.write
|
41
|
+
or allowed_permissions.execute
|
42
|
+
):
|
39
43
|
return False
|
40
|
-
for perm in [
|
44
|
+
for perm in ["read", "write", "execute"]:
|
41
45
|
if getattr(perms, perm) and not getattr(allowed_permissions, perm):
|
42
46
|
return False
|
43
47
|
return True
|
44
48
|
|
45
49
|
def get_tools(self):
|
46
|
-
"""Return the list of enabled tools managed by this provider, filtered by allowed permissions."""
|
47
|
-
|
50
|
+
"""Return the list of enabled tools managed by this provider, filtered by allowed permissions and disabled tools."""
|
51
|
+
from janito.tools.disabled_tools import is_tool_disabled
|
52
|
+
|
53
|
+
tools = [
|
54
|
+
tool
|
55
|
+
for tool in self._tools
|
56
|
+
if self.is_tool_allowed(tool)
|
57
|
+
and not is_tool_disabled(getattr(tool, "tool_name", str(tool)))
|
58
|
+
]
|
48
59
|
return tools
|
49
60
|
|
50
61
|
def set_allowed_permissions(self, allowed_permissions):
|
51
62
|
"""Set the allowed permissions at runtime. This now updates the global AllowedPermissionsState only."""
|
52
63
|
from janito.tools.permissions import set_global_allowed_permissions
|
64
|
+
|
53
65
|
set_global_allowed_permissions(allowed_permissions)
|
54
66
|
|
55
67
|
def add_tool(self, tool):
|
56
68
|
self._tools.append(tool)
|
57
69
|
|
58
|
-
|
59
|
-
self._tools = []
|
70
|
+
|
60
71
|
|
61
72
|
def _validate_arguments_against_schema(self, arguments: dict, schema: dict):
|
62
73
|
properties = schema.get("properties", {})
|
@@ -134,15 +145,14 @@ class ToolsAdapterBase:
|
|
134
145
|
if not accepts_kwargs:
|
135
146
|
unexpected = [k for k in arguments.keys() if k not in params]
|
136
147
|
if unexpected:
|
137
|
-
return (
|
138
|
-
"Unexpected argument(s): " + ", ".join(sorted(unexpected))
|
139
|
-
)
|
148
|
+
return "Unexpected argument(s): " + ", ".join(sorted(unexpected))
|
140
149
|
|
141
150
|
# Check for missing required arguments (ignoring *args / **kwargs / self)
|
142
151
|
required_params = [
|
143
152
|
name
|
144
153
|
for name, p in params.items()
|
145
|
-
if p.kind
|
154
|
+
if p.kind
|
155
|
+
in (
|
146
156
|
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
147
157
|
inspect.Parameter.KEYWORD_ONLY,
|
148
158
|
)
|
@@ -163,45 +173,63 @@ class ToolsAdapterBase:
|
|
163
173
|
self._ensure_tool_exists(tool, tool_name, request_id, arguments)
|
164
174
|
func = self._get_tool_callable(tool)
|
165
175
|
|
166
|
-
validation_error = self._validate_tool_arguments(
|
176
|
+
validation_error = self._validate_tool_arguments(
|
177
|
+
tool, func, arguments, tool_name, request_id
|
178
|
+
)
|
167
179
|
if validation_error:
|
168
180
|
return validation_error
|
169
181
|
|
170
182
|
# --- SECURITY: Path restriction enforcement ---
|
171
|
-
if not getattr(self,
|
172
|
-
workdir = getattr(self,
|
183
|
+
if not getattr(self, "unrestricted_paths", False):
|
184
|
+
workdir = getattr(self, "workdir", None)
|
173
185
|
# Ensure workdir is always set; default to current working directory.
|
174
186
|
if not workdir:
|
175
187
|
import os
|
188
|
+
|
176
189
|
workdir = os.getcwd()
|
177
|
-
from janito.tools.path_security import
|
178
|
-
|
190
|
+
from janito.tools.path_security import (
|
191
|
+
validate_paths_in_arguments,
|
192
|
+
PathSecurityError,
|
193
|
+
)
|
194
|
+
|
195
|
+
schema = getattr(tool, "schema", None)
|
179
196
|
try:
|
180
197
|
validate_paths_in_arguments(arguments, workdir, schema=schema)
|
181
198
|
except PathSecurityError as sec_err:
|
182
199
|
# Publish both a ToolCallError and a user-facing ReportEvent for path security errors
|
183
|
-
self._publish_tool_call_error(
|
200
|
+
self._publish_tool_call_error(
|
201
|
+
tool_name, request_id, str(sec_err), arguments
|
202
|
+
)
|
184
203
|
if self._event_bus:
|
185
|
-
from janito.report_events import
|
204
|
+
from janito.report_events import (
|
205
|
+
ReportEvent,
|
206
|
+
ReportSubtype,
|
207
|
+
ReportAction,
|
208
|
+
)
|
209
|
+
|
186
210
|
self._event_bus.publish(
|
187
211
|
ReportEvent(
|
188
212
|
subtype=ReportSubtype.ERROR,
|
189
213
|
message=f"[SECURITY] Path access denied: {sec_err}",
|
190
214
|
action=ReportAction.EXECUTE,
|
191
215
|
tool=tool_name,
|
192
|
-
context={"arguments": arguments, "request_id": request_id}
|
216
|
+
context={"arguments": arguments, "request_id": request_id},
|
193
217
|
)
|
194
218
|
)
|
195
219
|
return f"Security error: {sec_err}"
|
196
220
|
# --- END SECURITY ---
|
197
221
|
|
198
222
|
self._publish_tool_call_started(tool_name, request_id, arguments)
|
199
|
-
self._print_verbose(
|
223
|
+
self._print_verbose(
|
224
|
+
f"[tools-adapter] Executing tool: {tool_name} with arguments: {arguments}"
|
225
|
+
)
|
200
226
|
try:
|
201
227
|
result = self.execute(tool, **(arguments or {}), **kwargs)
|
202
228
|
except Exception as e:
|
203
229
|
self._handle_execution_error(tool_name, request_id, e, arguments)
|
204
|
-
self._print_verbose(
|
230
|
+
self._print_verbose(
|
231
|
+
f"[tools-adapter] Tool execution finished: {tool_name} -> {result}"
|
232
|
+
)
|
205
233
|
self._publish_tool_call_finished(tool_name, request_id, result)
|
206
234
|
return result
|
207
235
|
|
@@ -212,9 +240,13 @@ class ToolsAdapterBase:
|
|
212
240
|
return sig_error
|
213
241
|
schema = getattr(tool, "schema", None)
|
214
242
|
if schema and arguments is not None:
|
215
|
-
validation_error = self._validate_arguments_against_schema(
|
243
|
+
validation_error = self._validate_arguments_against_schema(
|
244
|
+
arguments, schema
|
245
|
+
)
|
216
246
|
if validation_error:
|
217
|
-
self._publish_tool_call_error(
|
247
|
+
self._publish_tool_call_error(
|
248
|
+
tool_name, request_id, validation_error, arguments
|
249
|
+
)
|
218
250
|
return validation_error
|
219
251
|
return None
|
220
252
|
|