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
@@ -0,0 +1,80 @@
|
|
1
|
+
"""
|
2
|
+
Profile selection logic for Janito Chat CLI using questionary.
|
3
|
+
"""
|
4
|
+
import questionary
|
5
|
+
from questionary import Style
|
6
|
+
|
7
|
+
def select_profile():
|
8
|
+
choices = [
|
9
|
+
"helpful assistant",
|
10
|
+
"developer",
|
11
|
+
"using role...",
|
12
|
+
"full custom system prompt..."
|
13
|
+
]
|
14
|
+
custom_style = Style([
|
15
|
+
("highlighted", "bg:#00aaff #ffffff"), # background for item under cursor
|
16
|
+
("question", "fg:#00aaff bold"),
|
17
|
+
])
|
18
|
+
answer = questionary.select(
|
19
|
+
"Select a profile to use:",
|
20
|
+
choices=choices,
|
21
|
+
default=None,
|
22
|
+
style=custom_style
|
23
|
+
).ask()
|
24
|
+
if answer == "helpful assistant":
|
25
|
+
return {"profile": None, "profile_system_prompt": "You are an helpful assistant"}
|
26
|
+
if answer == "using role...":
|
27
|
+
role_name = questionary.text("Enter the role name:").ask()
|
28
|
+
return f"role:{role_name}"
|
29
|
+
elif answer == "full custom system prompt...":
|
30
|
+
from prompt_toolkit import PromptSession
|
31
|
+
from prompt_toolkit.key_binding import KeyBindings
|
32
|
+
from prompt_toolkit.enums import EditingMode
|
33
|
+
from prompt_toolkit.formatted_text import HTML
|
34
|
+
from .prompt_style import chat_shell_style
|
35
|
+
|
36
|
+
mode = {"multiline": False}
|
37
|
+
bindings = KeyBindings()
|
38
|
+
|
39
|
+
@bindings.add("c-r")
|
40
|
+
def _(event):
|
41
|
+
pass
|
42
|
+
|
43
|
+
@bindings.add("f12")
|
44
|
+
def _(event):
|
45
|
+
buf = event.app.current_buffer
|
46
|
+
buf.text = "Do It"
|
47
|
+
buf.validate_and_handle()
|
48
|
+
|
49
|
+
def get_toolbar():
|
50
|
+
if mode["multiline"]:
|
51
|
+
return HTML("<b>Multiline mode (Esc+Enter to submit). Type /single to switch.</b>")
|
52
|
+
else:
|
53
|
+
return HTML("<b>Single-line mode (Enter to submit). Type /multi for multiline.</b>")
|
54
|
+
|
55
|
+
session = PromptSession(
|
56
|
+
multiline=False,
|
57
|
+
key_bindings=bindings,
|
58
|
+
editing_mode=EditingMode.EMACS,
|
59
|
+
bottom_toolbar=get_toolbar,
|
60
|
+
style=chat_shell_style,
|
61
|
+
)
|
62
|
+
prompt_icon = HTML("<inputline>📝 </inputline>")
|
63
|
+
while True:
|
64
|
+
response = session.prompt(prompt_icon)
|
65
|
+
if not mode["multiline"] and response.strip() == "/multi":
|
66
|
+
mode["multiline"] = True
|
67
|
+
session.multiline = True
|
68
|
+
continue
|
69
|
+
elif mode["multiline"] and response.strip() == "/single":
|
70
|
+
mode["multiline"] = False
|
71
|
+
session.multiline = False
|
72
|
+
continue
|
73
|
+
else:
|
74
|
+
sanitized = response.strip()
|
75
|
+
try:
|
76
|
+
sanitized.encode("utf-8")
|
77
|
+
except UnicodeEncodeError:
|
78
|
+
sanitized = sanitized.encode("utf-8", errors="replace").decode("utf-8")
|
79
|
+
return {"profile": None, "profile_system_prompt": sanitized}
|
80
|
+
return answer
|
@@ -1,21 +1,21 @@
|
|
1
|
-
from prompt_toolkit.completion import Completer, Completion
|
2
|
-
from janito.cli.chat_mode.shell.commands import get_shell_command_names
|
3
|
-
|
4
|
-
|
5
|
-
class ShellCommandCompleter(Completer):
|
6
|
-
"""
|
7
|
-
Provides autocomplete suggestions for shell commands starting with '/'.
|
8
|
-
Uses the COMMAND_HANDLERS registry for available commands.
|
9
|
-
"""
|
10
|
-
|
11
|
-
def __init__(self):
|
12
|
-
# Only commands starting with '/'
|
13
|
-
self.commands = get_shell_command_names()
|
14
|
-
|
15
|
-
def get_completions(self, document, complete_event):
|
16
|
-
text = document.text_before_cursor
|
17
|
-
if text.startswith("/"):
|
18
|
-
prefix = text[1:]
|
19
|
-
for cmd in self.commands:
|
20
|
-
if cmd[1:].startswith(prefix):
|
21
|
-
yield Completion(cmd, start_position=-(len(prefix) + 1))
|
1
|
+
from prompt_toolkit.completion import Completer, Completion
|
2
|
+
from janito.cli.chat_mode.shell.commands import get_shell_command_names
|
3
|
+
|
4
|
+
|
5
|
+
class ShellCommandCompleter(Completer):
|
6
|
+
"""
|
7
|
+
Provides autocomplete suggestions for shell commands starting with '/'.
|
8
|
+
Uses the COMMAND_HANDLERS registry for available commands.
|
9
|
+
"""
|
10
|
+
|
11
|
+
def __init__(self):
|
12
|
+
# Only commands starting with '/'
|
13
|
+
self.commands = get_shell_command_names()
|
14
|
+
|
15
|
+
def get_completions(self, document, complete_event):
|
16
|
+
text = document.text_before_cursor
|
17
|
+
if text.startswith("/"):
|
18
|
+
prefix = text[1:]
|
19
|
+
for cmd in self.commands:
|
20
|
+
if cmd[1:].startswith(prefix):
|
21
|
+
yield Completion(cmd, start_position=-(len(prefix) + 1))
|
@@ -1,21 +1,26 @@
|
|
1
1
|
from .base import ShellCmdHandler
|
2
|
-
from .edit import EditShellHandler
|
3
2
|
from .history_view import ViewShellHandler
|
4
3
|
from .lang import LangShellHandler
|
5
4
|
from .livelogs import LivelogsShellHandler
|
6
5
|
from .prompt import PromptShellHandler, RoleShellHandler, ProfileShellHandler
|
7
6
|
from .multi import MultiShellHandler
|
7
|
+
from .model import ModelShellHandler
|
8
8
|
from .role import RoleCommandShellHandler
|
9
9
|
from .session import HistoryShellHandler
|
10
|
-
from .termweb_log import TermwebLogTailShellHandler
|
11
10
|
from .tools import ToolsShellHandler
|
12
11
|
from .help import HelpShellHandler
|
13
12
|
from janito.cli.console import shared_console
|
14
13
|
|
15
14
|
COMMAND_HANDLERS = {
|
16
|
-
"/
|
17
|
-
"janito.cli.chat_mode.shell.commands.
|
18
|
-
).
|
15
|
+
"/execute": __import__(
|
16
|
+
"janito.cli.chat_mode.shell.commands.execute", fromlist=["ExecuteShellHandler"]
|
17
|
+
).ExecuteShellHandler,
|
18
|
+
"/read": __import__(
|
19
|
+
"janito.cli.chat_mode.shell.commands.read", fromlist=["ReadShellHandler"]
|
20
|
+
).ReadShellHandler,
|
21
|
+
"/write": __import__(
|
22
|
+
"janito.cli.chat_mode.shell.commands.write", fromlist=["WriteShellHandler"]
|
23
|
+
).WriteShellHandler,
|
19
24
|
"/clear": __import__(
|
20
25
|
"janito.cli.chat_mode.shell.commands.clear", fromlist=["ClearShellHandler"]
|
21
26
|
).ClearShellHandler,
|
@@ -23,7 +28,7 @@ COMMAND_HANDLERS = {
|
|
23
28
|
"janito.cli.chat_mode.shell.commands.conversation_restart",
|
24
29
|
fromlist=["RestartShellHandler"],
|
25
30
|
).RestartShellHandler,
|
26
|
-
|
31
|
+
|
27
32
|
"/view": ViewShellHandler,
|
28
33
|
"/lang": LangShellHandler,
|
29
34
|
"/livelogs": LivelogsShellHandler,
|
@@ -31,8 +36,9 @@ COMMAND_HANDLERS = {
|
|
31
36
|
"/role": RoleShellHandler,
|
32
37
|
"/profile": ProfileShellHandler,
|
33
38
|
"/history": HistoryShellHandler,
|
34
|
-
|
39
|
+
|
35
40
|
"/tools": ToolsShellHandler,
|
41
|
+
"/model": ModelShellHandler,
|
36
42
|
"/multi": MultiShellHandler,
|
37
43
|
"/help": HelpShellHandler,
|
38
44
|
}
|
@@ -1,12 +1,12 @@
|
|
1
|
-
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
2
|
-
from janito.cli.console import shared_console
|
3
|
-
|
4
|
-
|
5
|
-
class ClearShellHandler(ShellCmdHandler):
|
6
|
-
help_text = "Clear the terminal screen using Rich console."
|
7
|
-
|
8
|
-
def run(self):
|
9
|
-
shared_console.clear()
|
10
|
-
# Optionally show a message after clearing
|
11
|
-
# shared_console.print("[green]Screen cleared.[/green]")
|
12
|
-
return None
|
1
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
2
|
+
from janito.cli.console import shared_console
|
3
|
+
|
4
|
+
|
5
|
+
class ClearShellHandler(ShellCmdHandler):
|
6
|
+
help_text = "Clear the terminal screen using Rich console."
|
7
|
+
|
8
|
+
def run(self):
|
9
|
+
shared_console.clear()
|
10
|
+
# Optionally show a message after clearing
|
11
|
+
# shared_console.print("[green]Screen cleared.[/green]")
|
12
|
+
return None
|
@@ -37,6 +37,12 @@ def handle_restart(shell_state=None):
|
|
37
37
|
# Reset conversation history using the agent's method
|
38
38
|
if hasattr(shell_state, "agent") and shell_state.agent:
|
39
39
|
shell_state.agent.reset_conversation_history()
|
40
|
+
# Reset system prompt to original template context if available
|
41
|
+
if hasattr(shell_state.agent, "_original_template_vars"):
|
42
|
+
shell_state.agent._template_vars = shell_state.agent._original_template_vars.copy()
|
43
|
+
if hasattr(shell_state.agent, "_refresh_system_prompt_from_template"):
|
44
|
+
shell_state.agent._refresh_system_prompt_from_template()
|
45
|
+
# No need to print the system prompt after restart
|
40
46
|
|
41
47
|
# Reset tool use tracker
|
42
48
|
try:
|
@@ -63,6 +69,30 @@ def handle_restart(shell_state=None):
|
|
63
69
|
f"[bold yellow]Warning: Failed to reset PerformanceCollector token info:[/bold yellow] {e}"
|
64
70
|
)
|
65
71
|
|
72
|
+
# Restore tool permissions to the CLI default on restart
|
73
|
+
try:
|
74
|
+
from janito.tools.permissions import set_global_allowed_permissions, get_default_allowed_permissions
|
75
|
+
import janito.tools
|
76
|
+
default_perms = get_default_allowed_permissions()
|
77
|
+
if default_perms is not None:
|
78
|
+
set_global_allowed_permissions(default_perms)
|
79
|
+
janito.tools.local_tools_adapter.set_allowed_permissions(default_perms)
|
80
|
+
msg = None
|
81
|
+
|
82
|
+
else:
|
83
|
+
from janito.tools.tool_base import ToolPermissions
|
84
|
+
set_global_allowed_permissions(ToolPermissions(read=False, write=False, execute=False))
|
85
|
+
janito.tools.local_tools_adapter.set_allowed_permissions(ToolPermissions(read=False, write=False, execute=False))
|
86
|
+
msg = "[green]All tool permissions have been set to OFF (read, write, execute = False).[/green]"
|
87
|
+
# Refresh system prompt to reflect new permissions
|
88
|
+
if hasattr(shell_state, "agent") and shell_state.agent and hasattr(shell_state.agent, "_refresh_system_prompt_from_template"):
|
89
|
+
shell_state.agent._refresh_system_prompt_from_template()
|
90
|
+
if msg:
|
91
|
+
shared_console.print(msg)
|
92
|
+
|
93
|
+
except Exception as e:
|
94
|
+
shared_console.print(f"[yellow]Warning: Failed to restore tool permissions: {e}[/yellow]")
|
95
|
+
|
66
96
|
shared_console.print(
|
67
97
|
"[bold green]Conversation history has been started (context reset).[/bold green]"
|
68
98
|
)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
|
4
|
+
class ExecuteShellHandler(ShellCmdHandler):
|
5
|
+
help_text = "/execute on|off: Enable or disable code and command execution tools. Usage: /execute on or /execute off."
|
6
|
+
|
7
|
+
def run(self):
|
8
|
+
if not self.shell_state:
|
9
|
+
shared_console.print("[red]Shell state unavailable.[/red]")
|
10
|
+
return
|
11
|
+
arg = (self.after_cmd_line or "").strip().lower()
|
12
|
+
if arg not in ("on", "off"):
|
13
|
+
shared_console.print("[yellow]Usage: /execute on|off[/yellow]")
|
14
|
+
return
|
15
|
+
enable = arg == "on"
|
16
|
+
# Dynamically enable/disable execution tools in the registry
|
17
|
+
try:
|
18
|
+
from janito.tools.permissions import set_global_allowed_permissions, get_global_allowed_permissions
|
19
|
+
from janito.tools.tool_base import ToolPermissions
|
20
|
+
current_perms = get_global_allowed_permissions()
|
21
|
+
new_perms = ToolPermissions(
|
22
|
+
read=getattr(current_perms, 'read', False),
|
23
|
+
write=getattr(current_perms, 'write', False),
|
24
|
+
execute=enable
|
25
|
+
)
|
26
|
+
set_global_allowed_permissions(new_perms)
|
27
|
+
# Also update the singleton tools registry permissions
|
28
|
+
import janito.tools
|
29
|
+
janito.tools.local_tools_adapter.set_allowed_permissions(new_perms)
|
30
|
+
|
31
|
+
except Exception as e:
|
32
|
+
shared_console.print(f"[yellow]Warning: Could not update execution tools dynamically: {e}[/yellow]")
|
33
|
+
# Refresh system prompt if agent is available
|
34
|
+
agent = getattr(self.shell_state, "agent", None)
|
35
|
+
if agent:
|
36
|
+
if hasattr(agent, "_refresh_system_prompt_from_template"):
|
37
|
+
agent._refresh_system_prompt_from_template()
|
38
|
+
# No need to print the system prompt after permission change
|
39
|
+
if enable:
|
40
|
+
shared_console.print("[green]Execution tools ENABLED. Tools can now execute code and commands.[/green]")
|
41
|
+
else:
|
42
|
+
shared_console.print("[yellow]Execution tools DISABLED. Tools cannot run code or commands.[/yellow]")
|
@@ -6,11 +6,14 @@ class HelpShellHandler(ShellCmdHandler):
|
|
6
6
|
help_text = "Show this help message"
|
7
7
|
|
8
8
|
def run(self):
|
9
|
-
from . import
|
10
|
-
|
11
|
-
) # Import moved inside method to avoid circular import
|
9
|
+
from . import COMMAND_HANDLERS
|
10
|
+
from ._priv_check import user_has_any_privileges
|
12
11
|
|
13
12
|
shared_console.print("[bold magenta]Available commands:[/bold magenta]")
|
14
13
|
for cmd, handler_cls in sorted(COMMAND_HANDLERS.items()):
|
15
14
|
help_text = getattr(handler_cls, "help_text", "")
|
16
15
|
shared_console.print(f"[cyan]{cmd}[/cyan]: {help_text}")
|
16
|
+
|
17
|
+
# After help, print privilege info if user has no privileges
|
18
|
+
if not user_has_any_privileges():
|
19
|
+
shared_console.print("[yellow]Note: You currently have no privileges enabled. If you need to interact with files or the system, enable permissions using /read on, /write on, or /execute on.[/yellow]")
|
@@ -0,0 +1,28 @@
|
|
1
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
2
|
+
from janito.cli.console import shared_console
|
3
|
+
from janito.cli.config import config
|
4
|
+
|
5
|
+
from janito.cli.cli_commands.show_config import resolve_effective_model
|
6
|
+
|
7
|
+
class ModelShellHandler(ShellCmdHandler):
|
8
|
+
help_text = "Change or show the current LLM model (usage: /model [MODEL_NAME])"
|
9
|
+
|
10
|
+
def run(self):
|
11
|
+
model_name = self.after_cmd_line.strip()
|
12
|
+
if not model_name:
|
13
|
+
# Show effective model
|
14
|
+
provider = config.get("provider")
|
15
|
+
effective_model = resolve_effective_model(provider) if provider else None
|
16
|
+
if effective_model:
|
17
|
+
shared_console.print(f"[bold green]Current effective model:[/bold green] {effective_model}")
|
18
|
+
else:
|
19
|
+
shared_console.print("[bold yellow]No model is currently set.[/bold yellow]")
|
20
|
+
return
|
21
|
+
# Set new model (global override)
|
22
|
+
config.runtime_set("model", model_name)
|
23
|
+
# Update agent's model in shell_state if possible
|
24
|
+
agent = getattr(self.shell_state, "agent", None)
|
25
|
+
if agent is not None and hasattr(agent, "reset_driver_config_to_model_defaults"):
|
26
|
+
agent.reset_driver_config_to_model_defaults(model_name)
|
27
|
+
shared_console.print(f"[bold green]Model and config reset to defaults for:[/bold green] {model_name}")
|
28
|
+
|
@@ -1,51 +1,51 @@
|
|
1
|
-
from prompt_toolkit.shortcuts import prompt
|
2
|
-
from prompt_toolkit.application.current import get_app
|
3
|
-
from prompt_toolkit.document import Document
|
4
|
-
from prompt_toolkit.key_binding import KeyBindings
|
5
|
-
from janito.cli.console import shared_console
|
6
|
-
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
7
|
-
|
8
|
-
|
9
|
-
class MultiShellHandler(ShellCmdHandler):
|
10
|
-
help_text = "Prompt for multi-line input and display the result. Usage: /multi"
|
11
|
-
|
12
|
-
def run(self):
|
13
|
-
shared_console.print(
|
14
|
-
"[bold blue]Entering multi-line input mode. Press Esc+Enter or Ctrl+D to submit, Ctrl+C to cancel.[/bold blue]"
|
15
|
-
)
|
16
|
-
# Prompt for multi-line input
|
17
|
-
bindings = KeyBindings()
|
18
|
-
submitted = {"value": None}
|
19
|
-
|
20
|
-
@bindings.add("escape", "enter")
|
21
|
-
def _(event):
|
22
|
-
buffer = event.app.current_buffer
|
23
|
-
submitted["value"] = buffer.text
|
24
|
-
event.app.exit(result=buffer.text)
|
25
|
-
|
26
|
-
# Support Ctrl+D
|
27
|
-
@bindings.add("c-d")
|
28
|
-
def _(event):
|
29
|
-
buffer = event.app.current_buffer
|
30
|
-
submitted["value"] = buffer.text
|
31
|
-
event.app.exit(result=buffer.text)
|
32
|
-
|
33
|
-
try:
|
34
|
-
user_input = prompt(
|
35
|
-
"Multi-line > ",
|
36
|
-
multiline=True,
|
37
|
-
key_bindings=bindings,
|
38
|
-
)
|
39
|
-
except (EOFError, KeyboardInterrupt):
|
40
|
-
shared_console.print("[red]Multi-line input cancelled.[/red]")
|
41
|
-
return
|
42
|
-
|
43
|
-
# Save input to history if available
|
44
|
-
user_input_history = getattr(self.shell_state, "user_input_history", None)
|
45
|
-
if user_input_history is not None:
|
46
|
-
user_input_history.append(user_input)
|
47
|
-
# Store input for main chat loop to consume as if just entered by the user
|
48
|
-
self.shell_state.injected_input = user_input
|
49
|
-
shared_console.print(
|
50
|
-
"[green]Multi-line input will be sent as your next chat prompt.[/green]"
|
51
|
-
)
|
1
|
+
from prompt_toolkit.shortcuts import prompt
|
2
|
+
from prompt_toolkit.application.current import get_app
|
3
|
+
from prompt_toolkit.document import Document
|
4
|
+
from prompt_toolkit.key_binding import KeyBindings
|
5
|
+
from janito.cli.console import shared_console
|
6
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
7
|
+
|
8
|
+
|
9
|
+
class MultiShellHandler(ShellCmdHandler):
|
10
|
+
help_text = "Prompt for multi-line input and display the result. Usage: /multi"
|
11
|
+
|
12
|
+
def run(self):
|
13
|
+
shared_console.print(
|
14
|
+
"[bold blue]Entering multi-line input mode. Press Esc+Enter or Ctrl+D to submit, Ctrl+C to cancel.[/bold blue]"
|
15
|
+
)
|
16
|
+
# Prompt for multi-line input
|
17
|
+
bindings = KeyBindings()
|
18
|
+
submitted = {"value": None}
|
19
|
+
|
20
|
+
@bindings.add("escape", "enter")
|
21
|
+
def _(event):
|
22
|
+
buffer = event.app.current_buffer
|
23
|
+
submitted["value"] = buffer.text
|
24
|
+
event.app.exit(result=buffer.text)
|
25
|
+
|
26
|
+
# Support Ctrl+D
|
27
|
+
@bindings.add("c-d")
|
28
|
+
def _(event):
|
29
|
+
buffer = event.app.current_buffer
|
30
|
+
submitted["value"] = buffer.text
|
31
|
+
event.app.exit(result=buffer.text)
|
32
|
+
|
33
|
+
try:
|
34
|
+
user_input = prompt(
|
35
|
+
"Multi-line > ",
|
36
|
+
multiline=True,
|
37
|
+
key_bindings=bindings,
|
38
|
+
)
|
39
|
+
except (EOFError, KeyboardInterrupt):
|
40
|
+
shared_console.print("[red]Multi-line input cancelled.[/red]")
|
41
|
+
return
|
42
|
+
|
43
|
+
# Save input to history if available
|
44
|
+
user_input_history = getattr(self.shell_state, "user_input_history", None)
|
45
|
+
if user_input_history is not None:
|
46
|
+
user_input_history.append(user_input)
|
47
|
+
# Store input for main chat loop to consume as if just entered by the user
|
48
|
+
self.shell_state.injected_input = user_input
|
49
|
+
shared_console.print(
|
50
|
+
"[green]Multi-line input will be sent as your next chat prompt.[/green]"
|
51
|
+
)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
|
4
|
+
class ReadShellHandler(ShellCmdHandler):
|
5
|
+
help_text = "/read on|off: Enable or disable read permissions for tools. Usage: /read on or /read off."
|
6
|
+
|
7
|
+
def run(self):
|
8
|
+
if not self.shell_state:
|
9
|
+
shared_console.print("[red]Shell state unavailable.[/red]")
|
10
|
+
return
|
11
|
+
arg = (self.after_cmd_line or "").strip().lower()
|
12
|
+
if arg not in ("on", "off"):
|
13
|
+
shared_console.print("[yellow]Usage: /read on|off[/yellow]")
|
14
|
+
return
|
15
|
+
enable = arg == "on"
|
16
|
+
try:
|
17
|
+
from janito.tools.permissions import set_global_allowed_permissions, get_global_allowed_permissions
|
18
|
+
from janito.tools.tool_base import ToolPermissions
|
19
|
+
current = get_global_allowed_permissions()
|
20
|
+
new_perms = ToolPermissions(read=enable, write=current.write, execute=current.execute)
|
21
|
+
set_global_allowed_permissions(new_perms)
|
22
|
+
# Also update the singleton tools registry permissions
|
23
|
+
import janito.tools
|
24
|
+
janito.tools.local_tools_adapter.set_allowed_permissions(new_perms)
|
25
|
+
|
26
|
+
except Exception as e:
|
27
|
+
shared_console.print(f"[yellow]Warning: Could not update read permissions dynamically: {e}[/yellow]")
|
28
|
+
# Refresh system prompt if agent is available
|
29
|
+
agent = getattr(self.shell_state, "agent", None)
|
30
|
+
if agent:
|
31
|
+
if hasattr(agent, "_refresh_system_prompt_from_template"):
|
32
|
+
agent._refresh_system_prompt_from_template()
|
33
|
+
# No need to print the system prompt after permission change
|
34
|
+
if enable:
|
35
|
+
shared_console.print("[green]Read permissions ENABLED. Tools can now read files and data.[/green]")
|
36
|
+
else:
|
37
|
+
shared_console.print("[yellow]Read permissions DISABLED. Tools cannot read files/data.[/yellow]")
|
@@ -6,37 +6,64 @@ class ToolsShellHandler(ShellCmdHandler):
|
|
6
6
|
|
7
7
|
def run(self):
|
8
8
|
try:
|
9
|
-
# Initialize allow_execution before use
|
10
|
-
allow_execution = False
|
11
|
-
if hasattr(self, 'shell_state') and self.shell_state is not None:
|
12
|
-
allow_execution = getattr(self.shell_state, 'allow_execution', False)
|
13
9
|
|
14
10
|
import janito.tools # Ensure all tools are registered
|
11
|
+
from janito.tools.permissions import get_global_allowed_permissions
|
15
12
|
registry = janito.tools.get_local_tools_adapter()
|
16
13
|
tools = registry.list_tools()
|
17
|
-
|
18
|
-
|
14
|
+
from rich.table import Table
|
15
|
+
shared_console.print("Registered tools:")
|
19
16
|
tool_instances = {t.tool_name: t for t in registry.get_tools()}
|
17
|
+
if not tools:
|
18
|
+
shared_console.print("No tools are enabled under the current permission settings.")
|
19
|
+
return
|
20
|
+
# Group tools by permission class
|
21
|
+
perm_groups = {}
|
22
|
+
def perm_class(perms):
|
23
|
+
if perms.execute:
|
24
|
+
if perms.read and perms.write:
|
25
|
+
return "read-write-execute"
|
26
|
+
elif perms.read:
|
27
|
+
return "read-execute"
|
28
|
+
elif perms.write:
|
29
|
+
return "write-execute"
|
30
|
+
else:
|
31
|
+
return "execute-only"
|
32
|
+
elif perms.read and perms.write:
|
33
|
+
return "read-write"
|
34
|
+
elif perms.read:
|
35
|
+
return "read-only"
|
36
|
+
elif perms.write:
|
37
|
+
return "write-only"
|
38
|
+
else:
|
39
|
+
return "none"
|
20
40
|
for tool in tools:
|
21
41
|
inst = tool_instances.get(tool, None)
|
22
|
-
|
23
|
-
if
|
24
|
-
|
42
|
+
perms = getattr(inst, 'permissions', None)
|
43
|
+
if not perms:
|
44
|
+
group = "unknown"
|
25
45
|
else:
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
46
|
+
group = perm_class(perms)
|
47
|
+
perm_groups.setdefault(group, []).append(tool)
|
48
|
+
# Build and print table
|
49
|
+
table = Table(title="Tools by Permission Class")
|
50
|
+
table.add_column("Permission Type", style="cyan", no_wrap=True)
|
51
|
+
table.add_column("Tools", style="magenta")
|
52
|
+
for group, tool_list in sorted(perm_groups.items()):
|
53
|
+
table.add_row(group, " ".join(sorted(tool_list)))
|
54
|
+
shared_console.print(table)
|
32
55
|
|
33
|
-
|
56
|
+
|
57
|
+
# Find all possible execution tools (by permission: execute=True)
|
34
58
|
exec_tools = []
|
35
59
|
for tool_instance in registry.get_tools():
|
36
|
-
|
60
|
+
perms = getattr(tool_instance, 'permissions', None)
|
61
|
+
if perms and perms.execute:
|
37
62
|
exec_tools.append(tool_instance.tool_name)
|
38
63
|
|
39
|
-
|
64
|
+
from janito.tools.permissions import get_global_allowed_permissions
|
65
|
+
perms = get_global_allowed_permissions()
|
66
|
+
if not perms.execute and exec_tools:
|
40
67
|
shared_console.print("[yellow]⚠️ Warning: Execution tools (e.g., commands, code execution) are disabled. Use -x to enable them.[/yellow]")
|
41
68
|
|
42
69
|
except Exception as e:
|
@@ -0,0 +1,37 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
|
4
|
+
class WriteShellHandler(ShellCmdHandler):
|
5
|
+
help_text = "/write on|off: Enable or disable write permissions for tools. Usage: /write on or /write off."
|
6
|
+
|
7
|
+
def run(self):
|
8
|
+
if not self.shell_state:
|
9
|
+
shared_console.print("[red]Shell state unavailable.[/red]")
|
10
|
+
return
|
11
|
+
arg = (self.after_cmd_line or "").strip().lower()
|
12
|
+
if arg not in ("on", "off"):
|
13
|
+
shared_console.print("[yellow]Usage: /write on|off[/yellow]")
|
14
|
+
return
|
15
|
+
enable = arg == "on"
|
16
|
+
try:
|
17
|
+
from janito.tools.permissions import set_global_allowed_permissions, get_global_allowed_permissions
|
18
|
+
from janito.tools.tool_base import ToolPermissions
|
19
|
+
current = get_global_allowed_permissions()
|
20
|
+
new_perms = ToolPermissions(read=current.read, write=enable, execute=current.execute)
|
21
|
+
set_global_allowed_permissions(new_perms)
|
22
|
+
# Also update the singleton tools registry permissions
|
23
|
+
import janito.tools
|
24
|
+
janito.tools.local_tools_adapter.set_allowed_permissions(new_perms)
|
25
|
+
|
26
|
+
except Exception as e:
|
27
|
+
shared_console.print(f"[yellow]Warning: Could not update write permissions dynamically: {e}[/yellow]")
|
28
|
+
# Refresh system prompt if agent is available
|
29
|
+
agent = getattr(self.shell_state, "agent", None)
|
30
|
+
if agent:
|
31
|
+
if hasattr(agent, "_refresh_system_prompt_from_template"):
|
32
|
+
agent._refresh_system_prompt_from_template()
|
33
|
+
# No need to print the system prompt after permission change
|
34
|
+
if enable:
|
35
|
+
shared_console.print("[green]Write permissions ENABLED. Tools can now write files and data.[/green]")
|
36
|
+
else:
|
37
|
+
shared_console.print("[yellow]Write permissions DISABLED. Tools cannot write files/data.[/yellow]")
|
Binary file
|