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.
Files changed (118) hide show
  1. janito/__init__.py +6 -7
  2. janito/__main__.py +4 -5
  3. janito/_version.py +55 -58
  4. janito/agent/setup_agent.py +308 -241
  5. janito/agent/templates/profiles/{system_prompt_template_software developer.txt.j2 → system_prompt_template_Developer_with_Python_Tools.txt.j2} +43 -39
  6. janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +3 -12
  7. janito/cli/__init__.py +9 -10
  8. janito/cli/chat_mode/bindings.py +38 -38
  9. janito/cli/chat_mode/chat_entry.py +21 -23
  10. janito/cli/chat_mode/prompt_style.py +22 -25
  11. janito/cli/chat_mode/script_runner.py +158 -154
  12. janito/cli/chat_mode/session.py +80 -35
  13. janito/cli/chat_mode/session_profile_select.py +61 -52
  14. janito/cli/chat_mode/shell/commands/__init__.py +1 -5
  15. janito/cli/chat_mode/shell/commands/_priv_check.py +1 -0
  16. janito/cli/chat_mode/shell/commands/bang.py +10 -3
  17. janito/cli/chat_mode/shell/commands/conversation_restart.py +24 -7
  18. janito/cli/chat_mode/shell/commands/execute.py +22 -7
  19. janito/cli/chat_mode/shell/commands/help.py +4 -1
  20. janito/cli/chat_mode/shell/commands/model.py +13 -5
  21. janito/cli/chat_mode/shell/commands/privileges.py +21 -0
  22. janito/cli/chat_mode/shell/commands/prompt.py +0 -2
  23. janito/cli/chat_mode/shell/commands/read.py +22 -5
  24. janito/cli/chat_mode/shell/commands/tools.py +15 -4
  25. janito/cli/chat_mode/shell/commands/write.py +22 -5
  26. janito/cli/chat_mode/shell/input_history.py +3 -1
  27. janito/cli/chat_mode/shell/session/manager.py +0 -2
  28. janito/cli/chat_mode/toolbar.py +25 -19
  29. janito/cli/cli_commands/list_models.py +1 -1
  30. janito/cli/cli_commands/list_providers.py +1 -0
  31. janito/cli/cli_commands/list_tools.py +35 -7
  32. janito/cli/cli_commands/model_utils.py +5 -3
  33. janito/cli/cli_commands/show_config.py +12 -0
  34. janito/cli/cli_commands/show_system_prompt.py +23 -9
  35. janito/cli/config.py +0 -13
  36. janito/cli/core/getters.py +2 -0
  37. janito/cli/core/runner.py +25 -8
  38. janito/cli/core/setters.py +13 -76
  39. janito/cli/main_cli.py +9 -25
  40. janito/cli/prompt_core.py +19 -18
  41. janito/cli/prompt_setup.py +6 -3
  42. janito/cli/rich_terminal_reporter.py +19 -5
  43. janito/cli/single_shot_mode/handler.py +104 -95
  44. janito/cli/verbose_output.py +5 -1
  45. janito/config_manager.py +4 -0
  46. janito/drivers/azure_openai/driver.py +27 -30
  47. janito/drivers/driver_registry.py +27 -27
  48. janito/drivers/openai/driver.py +452 -436
  49. janito/formatting_token.py +12 -4
  50. janito/llm/agent.py +15 -6
  51. janito/llm/driver.py +1 -0
  52. janito/provider_registry.py +139 -178
  53. janito/providers/__init__.py +2 -0
  54. janito/providers/anthropic/model_info.py +40 -41
  55. janito/providers/anthropic/provider.py +75 -80
  56. janito/providers/azure_openai/provider.py +9 -4
  57. janito/providers/deepseek/provider.py +5 -4
  58. janito/providers/google/model_info.py +4 -2
  59. janito/providers/google/provider.py +11 -5
  60. janito/providers/groq/__init__.py +1 -0
  61. janito/providers/groq/model_info.py +46 -0
  62. janito/providers/groq/provider.py +76 -0
  63. janito/providers/moonshotai/__init__.py +1 -0
  64. janito/providers/moonshotai/model_info.py +15 -0
  65. janito/providers/moonshotai/provider.py +89 -0
  66. janito/providers/openai/provider.py +6 -7
  67. janito/tools/__init__.py +2 -0
  68. janito/tools/adapters/local/__init__.py +67 -66
  69. janito/tools/adapters/local/adapter.py +21 -4
  70. janito/tools/adapters/local/ask_user.py +1 -0
  71. janito/tools/adapters/local/copy_file.py +1 -0
  72. janito/tools/adapters/local/create_directory.py +1 -0
  73. janito/tools/adapters/local/create_file.py +1 -0
  74. janito/tools/adapters/local/delete_text_in_file.py +2 -1
  75. janito/tools/adapters/local/fetch_url.py +1 -0
  76. janito/tools/adapters/local/find_files.py +7 -6
  77. janito/tools/adapters/local/get_file_outline/core.py +1 -0
  78. janito/tools/adapters/local/get_file_outline/java_outline.py +22 -15
  79. janito/tools/adapters/local/get_file_outline/search_outline.py +1 -0
  80. janito/tools/adapters/local/move_file.py +4 -3
  81. janito/tools/adapters/local/open_html_in_browser.py +15 -5
  82. janito/tools/adapters/local/open_url.py +1 -0
  83. janito/tools/adapters/local/python_code_run.py +1 -0
  84. janito/tools/adapters/local/python_command_run.py +1 -0
  85. janito/tools/adapters/local/python_file_run.py +1 -0
  86. janito/tools/adapters/local/read_files.py +55 -40
  87. janito/tools/adapters/local/remove_directory.py +1 -0
  88. janito/tools/adapters/local/remove_file.py +1 -0
  89. janito/tools/adapters/local/replace_text_in_file.py +4 -3
  90. janito/tools/adapters/local/run_bash_command.py +1 -0
  91. janito/tools/adapters/local/run_powershell_command.py +1 -0
  92. janito/tools/adapters/local/search_text/core.py +18 -17
  93. janito/tools/adapters/local/search_text/match_lines.py +5 -5
  94. janito/tools/adapters/local/search_text/pattern_utils.py +1 -1
  95. janito/tools/adapters/local/search_text/traverse_directory.py +7 -7
  96. janito/tools/adapters/local/validate_file_syntax/core.py +1 -1
  97. janito/tools/adapters/local/validate_file_syntax/html_validator.py +8 -1
  98. janito/tools/disabled_tools.py +68 -0
  99. janito/tools/path_security.py +18 -11
  100. janito/tools/permissions.py +6 -0
  101. janito/tools/permissions_parse.py +4 -3
  102. janito/tools/tool_base.py +11 -5
  103. janito/tools/tool_use_tracker.py +1 -4
  104. janito/tools/tool_utils.py +1 -1
  105. janito/tools/tools_adapter.py +57 -25
  106. {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/METADATA +411 -417
  107. janito-2.8.0.dist-info/RECORD +202 -0
  108. janito/cli/chat_mode/shell/commands/livelogs.py +0 -49
  109. janito/drivers/mistralai/driver.py +0 -41
  110. janito/providers/mistralai/model_info.py +0 -37
  111. janito/providers/mistralai/provider.py +0 -72
  112. janito/providers/provider_static_info.py +0 -18
  113. janito-2.6.1.dist-info/RECORD +0 -199
  114. /janito/agent/templates/profiles/{system_prompt_template_assistant.txt.j2 → system_prompt_template_model_conversation_without_tools_or_context.txt.j2} +0 -0
  115. {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/WHEEL +0 -0
  116. {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/entry_points.txt +0 -0
  117. {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/licenses/LICENSE +0 -0
  118. {janito-2.6.1.dist-info → janito-2.8.0.dist-info}/top_level.txt +0 -0
@@ -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
- self._port = None
34
+
34
35
  self._pid = None
35
36
  self._stdout_path = None
36
37
  self._stderr_path = None
37
- self.livereload_stderr_path = None
38
- self._status = "starting" # Tracks the current status (updated by background thread/UI)
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, provider_instance, llm_driver_config, role, verbose_tools, verbose_agent, allowed_permissions, profile, profile_system_prompt, conversation_history
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 = self.shell_state.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 = "developer"
126
+ profile = "Developer with Python Tools"
100
127
  else:
101
128
  profile = (
102
- "developer" if result == "software developer" else result
129
+ "Developer with Python Tools" if result == "Developer" else result
103
130
  )
104
131
  except ImportError:
105
- profile = "helpful assistant"
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 = "developer"
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(self, args, provider_instance, llm_driver_config, role, verbose_tools, verbose_agent, allowed_permissions, profile, profile_system_prompt, conversation_history):
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(__import__('janito.tools', fromlist=['get_local_tools_adapter']), 'get_local_tools_adapter')()
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(f"[yellow]Warning: Could not filter execution tools at startup: {e}[/yellow]")
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
- f"[bold green]Janito Chat Mode v{__version__}[/bold green]"
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 = '~' + cwd[len(home):]
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 user_has_any_privileges
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("[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]")
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(self.console, self.msg_count, usage, elapsed=elapsed)
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
- def _handle_helpful_assistant():
20
- return {"profile": "assistant", "profile_system_prompt": None}
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("<b>Multiline mode (Esc+Enter to submit). Type /single to switch.</b>")
35
+ return HTML(
36
+ "<b>Multiline mode (Esc+Enter to submit). Type /single to switch.</b>"
37
+ )
29
38
  else:
30
- return HTML("<b>Single-line mode (Enter to submit). Type /multi for multiline.</b>")
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
- response = session.prompt(prompt_icon)
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
- "helpful assistant",
92
- "developer",
93
- "software developer",
94
- "using role...",
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
- ("highlighted", "bg:#00aaff #ffffff"), # background for item under cursor
103
- ("question", "fg:#00aaff bold"),
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 == "helpful assistant":
113
- return _handle_helpful_assistant()
114
- if answer == "using role...":
115
- return _handle_using_role()
116
- elif answer == "full custom system prompt...":
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 == "software developer":
122
- # Return the content of the built-in software developer profile prompt
123
- with open("./janito/agent/templates/profiles/system_prompt_template_software_developer.txt.j2", "r", encoding="utf-8") as f:
124
- prompt = f.read().strip()
125
- return {"profile": "software developer", "profile_system_prompt": prompt}
126
- return answer
127
-
128
- choices = [
129
- "helpful assistant",
130
- "developer",
131
- "using role...",
132
- "full custom system prompt..."
133
- ]
134
- custom_style = Style([
135
- ("highlighted", "bg:#00aaff #ffffff"), # background for item under cursor
136
- ("question", "fg:#00aaff bold"),
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
- from .livelogs import LivelogsShellHandler
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,
@@ -1,5 +1,6 @@
1
1
  from janito.tools.permissions import get_global_allowed_permissions
2
2
 
3
+
3
4
  def user_has_any_privileges():
4
5
  perms = get_global_allowed_permissions()
5
6
  return perms.read or perms.write or perms.execute
@@ -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("[yellow]Launching interactive PowerShell. Type 'exit' to return.[/yellow]")
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("[yellow]Launching interactive Bash shell. Type 'exit' to return.[/yellow]")
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(["powershell.exe", "-Command", cmd], capture_output=True, text=True)
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 = shell_state.agent._original_template_vars.copy()
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 set_global_allowed_permissions, get_default_allowed_permissions
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
- set_global_allowed_permissions(ToolPermissions(read=False, write=False, execute=False))
61
- janito.tools.local_tools_adapter.set_allowed_permissions(ToolPermissions(read=False, write=False, execute=False))
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 hasattr(shell_state, "agent") and shell_state.agent and hasattr(shell_state.agent, "refresh_system_prompt_from_template"):
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(f"[yellow]Warning: Failed to restore tool permissions: {e}[/yellow]")
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 set_global_allowed_permissions, get_global_allowed_permissions
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, 'read', False),
23
- write=getattr(current_perms, 'write', False),
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(f"[yellow]Warning: Could not update execution tools dynamically: {e}[/yellow]")
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("[green]Execution tools ENABLED. Tools can now execute code and commands.[/green]")
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("[yellow]Execution tools DISABLED. Tools cannot run code or commands.[/yellow]")
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("[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]")
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(f"[bold green]Current effective model:[/bold green] {effective_model}")
18
+ shared_console.print(
19
+ f"[bold green]Current effective model:[/bold green] {effective_model}"
20
+ )
18
21
  else:
19
- shared_console.print("[bold yellow]No model is currently set.[/bold yellow]")
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(agent, "reset_driver_config_to_model_defaults"):
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(f"[bold green]Model and config reset to defaults for:[/bold green] {model_name}")
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]")
@@ -45,5 +45,3 @@ class RoleShellHandler(ShellCmdHandler):
45
45
  shared_console.print(
46
46
  f"[bold green]System role updated to:[/bold green] {new_role}"
47
47
  )
48
-
49
-