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/cli/chat_mode/session.py
CHANGED
@@ -25,17 +25,20 @@ from janito.cli.prompt_setup import setup_agent_and_prompt_handler
|
|
25
25
|
|
26
26
|
import time
|
27
27
|
|
28
|
+
|
28
29
|
class ChatShellState:
|
29
30
|
def __init__(self, mem_history, conversation_history):
|
30
31
|
self.mem_history = mem_history
|
31
32
|
self.conversation_history = conversation_history
|
32
33
|
self.paste_mode = False
|
33
|
-
|
34
|
+
|
34
35
|
self._pid = None
|
35
36
|
self._stdout_path = None
|
36
37
|
self._stderr_path = None
|
37
|
-
|
38
|
-
self._status =
|
38
|
+
|
39
|
+
self._status = (
|
40
|
+
"starting" # Tracks the current status (updated by background thread/UI)
|
41
|
+
)
|
39
42
|
|
40
43
|
self.last_usage_info = {}
|
41
44
|
self.last_elapsed = None
|
@@ -44,6 +47,8 @@ class ChatShellState:
|
|
44
47
|
self.agent = None
|
45
48
|
self.main_agent = None
|
46
49
|
self.main_enabled = False
|
50
|
+
self.no_tools_mode = False
|
51
|
+
|
47
52
|
|
48
53
|
class ChatSession:
|
49
54
|
def __init__(
|
@@ -67,53 +72,88 @@ class ChatSession:
|
|
67
72
|
self.provider_instance = provider_instance
|
68
73
|
self.llm_driver_config = llm_driver_config
|
69
74
|
|
70
|
-
profile, role, profile_system_prompt = self._select_profile_and_role(args, role)
|
75
|
+
profile, role, profile_system_prompt, no_tools_mode = self._select_profile_and_role(args, role)
|
76
|
+
# Propagate no_tools_mode flag to downstream components via args
|
77
|
+
if args is not None and not hasattr(args, 'no_tools_mode'):
|
78
|
+
try:
|
79
|
+
setattr(args, 'no_tools_mode', no_tools_mode)
|
80
|
+
except Exception:
|
81
|
+
pass
|
71
82
|
conversation_history = self._create_conversation_history()
|
72
83
|
self.agent, self._prompt_handler = self._setup_agent_and_prompt_handler(
|
73
|
-
args,
|
84
|
+
args,
|
85
|
+
provider_instance,
|
86
|
+
llm_driver_config,
|
87
|
+
role,
|
88
|
+
verbose_tools,
|
89
|
+
verbose_agent,
|
90
|
+
allowed_permissions,
|
91
|
+
profile,
|
92
|
+
profile_system_prompt,
|
93
|
+
conversation_history,
|
74
94
|
)
|
75
95
|
self.shell_state = ChatShellState(self.mem_history, conversation_history)
|
76
96
|
self.shell_state.agent = self.agent
|
97
|
+
# Set no_tools_mode if present
|
98
|
+
self.shell_state.no_tools_mode = bool(no_tools_mode)
|
77
99
|
self._filter_execution_tools()
|
78
100
|
from janito.perf_singleton import performance_collector
|
101
|
+
|
79
102
|
self.performance_collector = performance_collector
|
80
103
|
self.key_bindings = KeyBindingsFactory.create()
|
81
104
|
self._prompt_handler.agent = self.agent
|
82
|
-
self._prompt_handler.conversation_history =
|
105
|
+
self._prompt_handler.conversation_history = (
|
106
|
+
self.shell_state.conversation_history
|
107
|
+
)
|
83
108
|
self._support = False
|
84
|
-
self._maybe_enable_web_support(args)
|
85
109
|
|
86
110
|
def _select_profile_and_role(self, args, role):
|
87
111
|
profile = getattr(args, "profile", None) if args is not None else None
|
88
112
|
role_arg = getattr(args, "role", None) if args is not None else None
|
89
113
|
profile_system_prompt = None
|
114
|
+
no_tools_mode = False
|
90
115
|
if profile is None and role_arg is None:
|
91
116
|
try:
|
92
117
|
from janito.cli.chat_mode.session_profile_select import select_profile
|
118
|
+
|
93
119
|
result = select_profile()
|
94
120
|
if isinstance(result, dict):
|
95
121
|
profile = result.get("profile")
|
96
122
|
profile_system_prompt = result.get("profile_system_prompt")
|
123
|
+
no_tools_mode = result.get("no_tools_mode", False)
|
97
124
|
elif isinstance(result, str) and result.startswith("role:"):
|
98
125
|
role = result[len("role:") :].strip()
|
99
|
-
profile = "
|
126
|
+
profile = "Developer with Python Tools"
|
100
127
|
else:
|
101
128
|
profile = (
|
102
|
-
"
|
129
|
+
"Developer with Python Tools" if result == "Developer" else result
|
103
130
|
)
|
104
131
|
except ImportError:
|
105
|
-
profile = "
|
132
|
+
profile = "Raw Model Session (no tools, no context)"
|
106
133
|
if role_arg is not None:
|
107
134
|
role = role_arg
|
108
135
|
if profile is None:
|
109
|
-
profile = "
|
110
|
-
return profile, role, profile_system_prompt
|
136
|
+
profile = "Developer with Python Tools"
|
137
|
+
return profile, role, profile_system_prompt, no_tools_mode
|
111
138
|
|
112
139
|
def _create_conversation_history(self):
|
113
140
|
from janito.conversation_history import LLMConversationHistory
|
141
|
+
|
114
142
|
return LLMConversationHistory()
|
115
143
|
|
116
|
-
def _setup_agent_and_prompt_handler(
|
144
|
+
def _setup_agent_and_prompt_handler(
|
145
|
+
self,
|
146
|
+
args,
|
147
|
+
provider_instance,
|
148
|
+
llm_driver_config,
|
149
|
+
role,
|
150
|
+
verbose_tools,
|
151
|
+
verbose_agent,
|
152
|
+
allowed_permissions,
|
153
|
+
profile,
|
154
|
+
profile_system_prompt,
|
155
|
+
conversation_history,
|
156
|
+
):
|
117
157
|
return setup_agent_and_prompt_handler(
|
118
158
|
args=args,
|
119
159
|
provider_instance=provider_instance,
|
@@ -129,23 +169,16 @@ class ChatSession:
|
|
129
169
|
|
130
170
|
def _filter_execution_tools(self):
|
131
171
|
try:
|
132
|
-
getattr(
|
172
|
+
getattr(
|
173
|
+
__import__("janito.tools", fromlist=["get_local_tools_adapter"]),
|
174
|
+
"get_local_tools_adapter",
|
175
|
+
)()
|
133
176
|
except Exception as e:
|
134
|
-
self.console.print(
|
135
|
-
|
136
|
-
def _maybe_enable_web_support(self, args):
|
137
|
-
if args and getattr(args, "web", False):
|
138
|
-
self._support = True
|
139
|
-
self.shell_state._support = self._support
|
140
|
-
from janito.cli._starter import _start_and_watch
|
141
|
-
from janito.cli.config import get__port
|
142
|
-
import threading
|
143
|
-
from rich.console import Console
|
144
|
-
Console().print("[yellow]Starting in background...[/yellow]")
|
145
|
-
self._lock = threading.Lock()
|
146
|
-
_thread = _start_and_watch(
|
147
|
-
self.shell_state, self._lock, get__port()
|
177
|
+
self.console.print(
|
178
|
+
f"[yellow]Warning: Could not filter execution tools at startup: {e}[/yellow]"
|
148
179
|
)
|
180
|
+
|
181
|
+
_thread = _start_and_watch(self.shell_state, self._lock, get__port())
|
149
182
|
self._thread = _thread
|
150
183
|
else:
|
151
184
|
self.shell_state._support = False
|
@@ -154,22 +187,29 @@ class ChatSession:
|
|
154
187
|
def run(self):
|
155
188
|
self.console.clear()
|
156
189
|
from janito import __version__
|
190
|
+
|
191
|
+
self.console.print(f"[bold green]Janito Chat Mode v{__version__}[/bold green]")
|
157
192
|
self.console.print(
|
158
|
-
|
193
|
+
"[green]/help for commands /exit or Ctrl+C to quit[/green]"
|
159
194
|
)
|
160
|
-
self.console.print("[green]/help for commands /exit or Ctrl+C to quit[/green]")
|
161
195
|
import os
|
196
|
+
|
162
197
|
cwd = os.getcwd()
|
163
|
-
home = os.path.expanduser(
|
198
|
+
home = os.path.expanduser("~")
|
164
199
|
if cwd.startswith(home):
|
165
|
-
cwd_display =
|
200
|
+
cwd_display = "~" + cwd[len(home) :]
|
166
201
|
else:
|
167
202
|
cwd_display = cwd
|
168
203
|
self.console.print(f"[green]Working Dir:[/green] {cwd_display}")
|
169
204
|
|
170
|
-
from janito.cli.chat_mode.shell.commands._priv_check import
|
205
|
+
from janito.cli.chat_mode.shell.commands._priv_check import (
|
206
|
+
user_has_any_privileges,
|
207
|
+
)
|
208
|
+
|
171
209
|
if not user_has_any_privileges():
|
172
|
-
self.console.print(
|
210
|
+
self.console.print(
|
211
|
+
"[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]"
|
212
|
+
)
|
173
213
|
|
174
214
|
session = self._create_prompt_session()
|
175
215
|
self._chat_loop(session)
|
@@ -204,6 +244,7 @@ class ChatSession:
|
|
204
244
|
def _process_prompt(self, cmd_input):
|
205
245
|
try:
|
206
246
|
import time
|
247
|
+
|
207
248
|
final_event = (
|
208
249
|
self._prompt_handler.agent.last_event
|
209
250
|
if hasattr(self._prompt_handler.agent, "last_event")
|
@@ -215,8 +256,11 @@ class ChatSession:
|
|
215
256
|
elapsed = end_time - start_time
|
216
257
|
self.msg_count += 1
|
217
258
|
from janito.formatting_token import print_token_message_summary
|
259
|
+
|
218
260
|
usage = self.performance_collector.get_last_request_usage()
|
219
|
-
print_token_message_summary(
|
261
|
+
print_token_message_summary(
|
262
|
+
self.console, self.msg_count, usage, elapsed=elapsed
|
263
|
+
)
|
220
264
|
if final_event and hasattr(final_event, "metadata"):
|
221
265
|
exit_reason = (
|
222
266
|
final_event.metadata.get("exit_reason")
|
@@ -230,6 +274,7 @@ class ChatSession:
|
|
230
274
|
except Exception as exc:
|
231
275
|
self.console.print(f"[red]Exception in agent: {exc}[/red]")
|
232
276
|
import traceback
|
277
|
+
|
233
278
|
self.console.print(traceback.format_exc())
|
234
279
|
|
235
280
|
def _create_prompt_session(self):
|
@@ -16,20 +16,35 @@ from .prompt_style import chat_shell_style
|
|
16
16
|
Profile selection logic for Janito Chat CLI using questionary.
|
17
17
|
"""
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
|
20
|
+
def _handle_raw_model_session_no_tools():
|
21
|
+
return {
|
22
|
+
"profile": "model_conversation_without_tools_or_context",
|
23
|
+
"profile_system_prompt": None,
|
24
|
+
"no_tools_mode": True,
|
25
|
+
} # Raw Model Session (no tools, no context)
|
26
|
+
|
21
27
|
|
22
28
|
def _handle_using_role():
|
23
29
|
role_name = questionary.text("Enter the role name:").ask()
|
24
30
|
return f"role:{role_name}"
|
25
31
|
|
32
|
+
|
26
33
|
def _get_toolbar(mode):
|
27
34
|
if mode["multiline"]:
|
28
|
-
return HTML(
|
35
|
+
return HTML(
|
36
|
+
"<b>Multiline mode (Esc+Enter to submit). Type /single to switch.</b>"
|
37
|
+
)
|
29
38
|
else:
|
30
|
-
return HTML(
|
39
|
+
return HTML(
|
40
|
+
"<b>Single-line mode (Enter to submit). Type /multi for multiline.</b>"
|
41
|
+
)
|
42
|
+
|
31
43
|
|
32
44
|
def _handle_custom_system_prompt():
|
45
|
+
print(
|
46
|
+
"\n[Custom System Prompt]\nPlease enter the message that will be used as the model system prompt. This will define how the AI behaves for this session.\nYou can use /multi for multiline mode, and /single to return to single-line mode.\n"
|
47
|
+
)
|
33
48
|
mode = {"multiline": False}
|
34
49
|
bindings = KeyBindings()
|
35
50
|
|
@@ -52,7 +67,13 @@ def _handle_custom_system_prompt():
|
|
52
67
|
)
|
53
68
|
prompt_icon = HTML("<inputline>📝 </inputline>")
|
54
69
|
while True:
|
55
|
-
|
70
|
+
try:
|
71
|
+
response = session.prompt(prompt_icon)
|
72
|
+
except KeyboardInterrupt:
|
73
|
+
print("[Custom System Prompt] Exited by the user.")
|
74
|
+
import sys
|
75
|
+
|
76
|
+
sys.exit(0)
|
56
77
|
if not mode["multiline"] and response.strip() == "/multi":
|
57
78
|
mode["multiline"] = True
|
58
79
|
session.multiline = True
|
@@ -88,63 +109,51 @@ def _load_user_profiles():
|
|
88
109
|
def select_profile():
|
89
110
|
user_profiles = _load_user_profiles()
|
90
111
|
choices = [
|
91
|
-
"
|
92
|
-
"
|
93
|
-
"
|
94
|
-
"
|
95
|
-
"full custom system prompt..."
|
112
|
+
"Developer with Python Tools",
|
113
|
+
"Developer",
|
114
|
+
"Custom system prompt...",
|
115
|
+
"Raw Model Session (no tools, no context)",
|
96
116
|
]
|
97
117
|
# Add user profiles to choices
|
98
118
|
if user_profiles:
|
99
119
|
choices.extend(user_profiles.keys())
|
100
120
|
|
101
|
-
custom_style = Style(
|
102
|
-
|
103
|
-
|
104
|
-
|
121
|
+
custom_style = Style(
|
122
|
+
[
|
123
|
+
("highlighted", "bg:#00aaff #ffffff"), # background for item under cursor
|
124
|
+
("question", "fg:#00aaff bold"),
|
125
|
+
]
|
126
|
+
)
|
105
127
|
answer = questionary.select(
|
106
|
-
"Select a profile to use:",
|
107
|
-
choices=choices,
|
108
|
-
default=None,
|
109
|
-
style=custom_style
|
128
|
+
"Select a profile to use:", choices=choices, default=None, style=custom_style
|
110
129
|
).ask()
|
111
130
|
|
112
|
-
if answer
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
131
|
+
if not answer:
|
132
|
+
import sys
|
133
|
+
|
134
|
+
sys.exit(0)
|
135
|
+
|
136
|
+
if answer == "Raw Model Session (no tools, no context)":
|
137
|
+
return _handle_raw_model_session_no_tools()
|
138
|
+
elif answer == "Custom system prompt...":
|
117
139
|
return _handle_custom_system_prompt()
|
118
140
|
elif answer in user_profiles:
|
119
141
|
# Return the content of the user profile as a custom system prompt
|
120
142
|
return {"profile": None, "profile_system_prompt": user_profiles[answer]}
|
121
|
-
elif answer == "
|
122
|
-
# Return the content of the built-in
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
"
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
])
|
138
|
-
answer = questionary.select(
|
139
|
-
"Select a profile to use:",
|
140
|
-
choices=choices,
|
141
|
-
default=None,
|
142
|
-
style=custom_style
|
143
|
-
).ask()
|
144
|
-
if answer == "helpful assistant":
|
145
|
-
return _handle_helpful_assistant()
|
146
|
-
if answer == "using role...":
|
147
|
-
return _handle_using_role()
|
148
|
-
elif answer == "full custom system prompt...":
|
149
|
-
return _handle_custom_system_prompt()
|
143
|
+
elif answer == "Developer":
|
144
|
+
# Return the content of the built-in Developer profile prompt
|
145
|
+
from pathlib import Path
|
146
|
+
from jinja2 import Template
|
147
|
+
from janito.agent.setup_agent import _prepare_template_context
|
148
|
+
|
149
|
+
template_path = Path(
|
150
|
+
"./janito/agent/templates/profiles/system_prompt_template_Developer.txt.j2"
|
151
|
+
)
|
152
|
+
with open(template_path, "r", encoding="utf-8") as f:
|
153
|
+
template_content = f.read()
|
154
|
+
|
155
|
+
template = Template(template_content)
|
156
|
+
context = _prepare_template_context("developer", "Developer", None)
|
157
|
+
prompt = template.render(**context)
|
158
|
+
return {"profile": "Developer", "profile_system_prompt": prompt}
|
150
159
|
return answer
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from .base import ShellCmdHandler
|
2
2
|
from .history_view import ViewShellHandler
|
3
3
|
from .lang import LangShellHandler
|
4
|
-
|
4
|
+
|
5
5
|
from .prompt import PromptShellHandler, RoleShellHandler
|
6
6
|
from .multi import MultiShellHandler
|
7
7
|
from .model import ModelShellHandler
|
@@ -32,15 +32,11 @@ COMMAND_HANDLERS = {
|
|
32
32
|
"janito.cli.chat_mode.shell.commands.conversation_restart",
|
33
33
|
fromlist=["RestartShellHandler"],
|
34
34
|
).RestartShellHandler,
|
35
|
-
|
36
35
|
"/view": ViewShellHandler,
|
37
36
|
"/lang": LangShellHandler,
|
38
|
-
"/livelogs": LivelogsShellHandler,
|
39
37
|
"/prompt": PromptShellHandler,
|
40
38
|
"/role": RoleShellHandler,
|
41
|
-
|
42
39
|
"/history": HistoryShellHandler,
|
43
|
-
|
44
40
|
"/tools": ToolsShellHandler,
|
45
41
|
"/model": ModelShellHandler,
|
46
42
|
"/multi": MultiShellHandler,
|
@@ -4,6 +4,7 @@ from janito.platform_discovery import PlatformDiscovery
|
|
4
4
|
import subprocess
|
5
5
|
import sys
|
6
6
|
|
7
|
+
|
7
8
|
class BangShellHandler(ShellCmdHandler):
|
8
9
|
help_text = "!<cmd>: Run a shell command in the underlying shell (PowerShell or Bash). Usage: !ls -al or !Get-Process. Use ! with no command to launch an interactive shell."
|
9
10
|
|
@@ -15,16 +16,22 @@ class BangShellHandler(ShellCmdHandler):
|
|
15
16
|
if not cmd:
|
16
17
|
pd = PlatformDiscovery()
|
17
18
|
if pd.is_windows():
|
18
|
-
shared_console.print(
|
19
|
+
shared_console.print(
|
20
|
+
"[yellow]Launching interactive PowerShell. Type 'exit' to return.[/yellow]"
|
21
|
+
)
|
19
22
|
subprocess.run(["powershell.exe"], check=False)
|
20
23
|
else:
|
21
|
-
shared_console.print(
|
24
|
+
shared_console.print(
|
25
|
+
"[yellow]Launching interactive Bash shell. Type 'exit' to return.[/yellow]"
|
26
|
+
)
|
22
27
|
subprocess.run(["bash"], check=False)
|
23
28
|
return
|
24
29
|
pd = PlatformDiscovery()
|
25
30
|
if pd.is_windows():
|
26
31
|
shared_console.print(f"[cyan]Running in PowerShell:[/cyan] {cmd}")
|
27
|
-
completed = subprocess.run(
|
32
|
+
completed = subprocess.run(
|
33
|
+
["powershell.exe", "-Command", cmd], capture_output=True, text=True
|
34
|
+
)
|
28
35
|
else:
|
29
36
|
shared_console.print(f"[cyan]Running in Bash:[/cyan] {cmd}")
|
30
37
|
completed = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
@@ -16,7 +16,9 @@ def handle_restart(shell_state=None):
|
|
16
16
|
shell_state.agent.reset_conversation_history()
|
17
17
|
# Reset system prompt to original template context if available
|
18
18
|
if hasattr(shell_state.agent, "_original_template_vars"):
|
19
|
-
shell_state.agent._template_vars =
|
19
|
+
shell_state.agent._template_vars = (
|
20
|
+
shell_state.agent._original_template_vars.copy()
|
21
|
+
)
|
20
22
|
shell_state.agent.refresh_system_prompt_from_template()
|
21
23
|
# No need to print the system prompt after restart
|
22
24
|
|
@@ -47,27 +49,42 @@ def handle_restart(shell_state=None):
|
|
47
49
|
|
48
50
|
# Restore tool permissions to the CLI default on restart
|
49
51
|
try:
|
50
|
-
from janito.tools.permissions import
|
52
|
+
from janito.tools.permissions import (
|
53
|
+
set_global_allowed_permissions,
|
54
|
+
get_default_allowed_permissions,
|
55
|
+
)
|
51
56
|
import janito.tools
|
57
|
+
|
52
58
|
default_perms = get_default_allowed_permissions()
|
53
59
|
if default_perms is not None:
|
54
60
|
set_global_allowed_permissions(default_perms)
|
55
61
|
janito.tools.local_tools_adapter.set_allowed_permissions(default_perms)
|
56
62
|
msg = None
|
57
|
-
|
63
|
+
|
58
64
|
else:
|
59
65
|
from janito.tools.tool_base import ToolPermissions
|
60
|
-
|
61
|
-
|
66
|
+
|
67
|
+
set_global_allowed_permissions(
|
68
|
+
ToolPermissions(read=False, write=False, execute=False)
|
69
|
+
)
|
70
|
+
janito.tools.local_tools_adapter.set_allowed_permissions(
|
71
|
+
ToolPermissions(read=False, write=False, execute=False)
|
72
|
+
)
|
62
73
|
msg = "[green]All tool permissions have been set to OFF (read, write, execute = False).[/green]"
|
63
74
|
# Refresh system prompt to reflect new permissions
|
64
|
-
if
|
75
|
+
if (
|
76
|
+
hasattr(shell_state, "agent")
|
77
|
+
and shell_state.agent
|
78
|
+
and hasattr(shell_state.agent, "refresh_system_prompt_from_template")
|
79
|
+
):
|
65
80
|
shell_state.agent.refresh_system_prompt_from_template()
|
66
81
|
if msg:
|
67
82
|
shared_console.print(msg)
|
68
83
|
|
69
84
|
except Exception as e:
|
70
|
-
shared_console.print(
|
85
|
+
shared_console.print(
|
86
|
+
f"[yellow]Warning: Failed to restore tool permissions: {e}[/yellow]"
|
87
|
+
)
|
71
88
|
|
72
89
|
shared_console.print(
|
73
90
|
"[bold green]Conversation history has been started (context reset).[/bold green]"
|
@@ -1,10 +1,14 @@
|
|
1
1
|
from janito.cli.console import shared_console
|
2
2
|
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
3
|
|
4
|
+
|
4
5
|
class ExecuteShellHandler(ShellCmdHandler):
|
5
6
|
help_text = "/execute on|off: Enable or disable code and command execution tools. Usage: /execute on or /execute off."
|
6
7
|
|
7
8
|
def run(self):
|
9
|
+
if self.shell_state and getattr(self.shell_state, 'no_tools_mode', False):
|
10
|
+
shared_console.print("[yellow]No tools are available in this mode (no tools, no context).[/yellow]")
|
11
|
+
return
|
8
12
|
if not self.shell_state:
|
9
13
|
shared_console.print("[red]Shell state unavailable.[/red]")
|
10
14
|
return
|
@@ -15,27 +19,38 @@ class ExecuteShellHandler(ShellCmdHandler):
|
|
15
19
|
enable = arg == "on"
|
16
20
|
# Dynamically enable/disable execution tools in the registry
|
17
21
|
try:
|
18
|
-
from janito.tools.permissions import
|
22
|
+
from janito.tools.permissions import (
|
23
|
+
set_global_allowed_permissions,
|
24
|
+
get_global_allowed_permissions,
|
25
|
+
)
|
19
26
|
from janito.tools.tool_base import ToolPermissions
|
27
|
+
|
20
28
|
current_perms = get_global_allowed_permissions()
|
21
29
|
new_perms = ToolPermissions(
|
22
|
-
read=getattr(current_perms,
|
23
|
-
write=getattr(current_perms,
|
24
|
-
execute=enable
|
30
|
+
read=getattr(current_perms, "read", False),
|
31
|
+
write=getattr(current_perms, "write", False),
|
32
|
+
execute=enable,
|
25
33
|
)
|
26
34
|
set_global_allowed_permissions(new_perms)
|
27
35
|
# Also update the singleton tools registry permissions
|
28
36
|
import janito.tools
|
37
|
+
|
29
38
|
janito.tools.local_tools_adapter.set_allowed_permissions(new_perms)
|
30
39
|
|
31
40
|
except Exception as e:
|
32
|
-
shared_console.print(
|
41
|
+
shared_console.print(
|
42
|
+
f"[yellow]Warning: Could not update execution tools dynamically: {e}[/yellow]"
|
43
|
+
)
|
33
44
|
# Refresh system prompt if agent is available
|
34
45
|
agent = getattr(self.shell_state, "agent", None)
|
35
46
|
if agent:
|
36
47
|
agent.refresh_system_prompt_from_template()
|
37
48
|
# No need to print the system prompt after permission change
|
38
49
|
if enable:
|
39
|
-
shared_console.print(
|
50
|
+
shared_console.print(
|
51
|
+
"[green]Execution tools ENABLED. Tools can now execute code and commands.[/green]"
|
52
|
+
)
|
40
53
|
else:
|
41
|
-
shared_console.print(
|
54
|
+
shared_console.print(
|
55
|
+
"[yellow]Execution tools DISABLED. Tools cannot run code or commands.[/yellow]"
|
56
|
+
)
|
@@ -2,6 +2,7 @@ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
|
2
2
|
from janito.cli.console import shared_console
|
3
3
|
import os
|
4
4
|
|
5
|
+
|
5
6
|
class HelpShellHandler(ShellCmdHandler):
|
6
7
|
help_text = "Show this help message"
|
7
8
|
|
@@ -16,4 +17,6 @@ class HelpShellHandler(ShellCmdHandler):
|
|
16
17
|
|
17
18
|
# After help, print privilege info if user has no privileges
|
18
19
|
if not user_has_any_privileges():
|
19
|
-
shared_console.print(
|
20
|
+
shared_console.print(
|
21
|
+
"[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]"
|
22
|
+
)
|
@@ -4,6 +4,7 @@ from janito.cli.config import config
|
|
4
4
|
|
5
5
|
from janito.cli.cli_commands.show_config import resolve_effective_model
|
6
6
|
|
7
|
+
|
7
8
|
class ModelShellHandler(ShellCmdHandler):
|
8
9
|
help_text = "Change or show the current LLM model (usage: /model [MODEL_NAME])"
|
9
10
|
|
@@ -14,15 +15,22 @@ class ModelShellHandler(ShellCmdHandler):
|
|
14
15
|
provider = config.get("provider")
|
15
16
|
effective_model = resolve_effective_model(provider) if provider else None
|
16
17
|
if effective_model:
|
17
|
-
shared_console.print(
|
18
|
+
shared_console.print(
|
19
|
+
f"[bold green]Current effective model:[/bold green] {effective_model}"
|
20
|
+
)
|
18
21
|
else:
|
19
|
-
shared_console.print(
|
22
|
+
shared_console.print(
|
23
|
+
"[bold yellow]No model is currently set.[/bold yellow]"
|
24
|
+
)
|
20
25
|
return
|
21
26
|
# Set new model (global override)
|
22
27
|
config.runtime_set("model", model_name)
|
23
28
|
# Update agent's model in shell_state if possible
|
24
29
|
agent = getattr(self.shell_state, "agent", None)
|
25
|
-
if agent is not None and hasattr(
|
30
|
+
if agent is not None and hasattr(
|
31
|
+
agent, "reset_driver_config_to_model_defaults"
|
32
|
+
):
|
26
33
|
agent.reset_driver_config_to_model_defaults(model_name)
|
27
|
-
shared_console.print(
|
28
|
-
|
34
|
+
shared_console.print(
|
35
|
+
f"[bold green]Model and config reset to defaults for:[/bold green] {model_name}"
|
36
|
+
)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
|
4
|
+
class PrivilegesShellHandler(ShellCmdHandler):
|
5
|
+
help_text = "Show current tool privileges or availability."
|
6
|
+
|
7
|
+
def run(self):
|
8
|
+
# Check for no_tools_mode in shell_state
|
9
|
+
if self.shell_state and getattr(self.shell_state, 'no_tools_mode', False):
|
10
|
+
shared_console.print("[yellow]No tools are available in this mode (no tools, no context).[/yellow]")
|
11
|
+
return
|
12
|
+
try:
|
13
|
+
from janito.tools.permissions import get_global_allowed_permissions
|
14
|
+
perms = get_global_allowed_permissions()
|
15
|
+
lines = ["[bold]Current tool privileges:[/bold]"]
|
16
|
+
lines.append(f"Read: {'✅' if perms.read else '❌'}")
|
17
|
+
lines.append(f"Write: {'✅' if perms.write else '❌'}")
|
18
|
+
lines.append(f"Execute: {'✅' if perms.execute else '❌'}")
|
19
|
+
shared_console.print("\n".join(lines))
|
20
|
+
except Exception as e:
|
21
|
+
shared_console.print(f"[red]Error fetching privileges: {e}[/red]")
|