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
@@ -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 ReadShellHandler(ShellCmdHandler):
5
6
  help_text = "/read on|off: Enable or disable read permissions for tools. Usage: /read on or /read 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
@@ -14,23 +18,36 @@ class ReadShellHandler(ShellCmdHandler):
14
18
  return
15
19
  enable = arg == "on"
16
20
  try:
17
- from janito.tools.permissions import set_global_allowed_permissions, get_global_allowed_permissions
21
+ from janito.tools.permissions import (
22
+ set_global_allowed_permissions,
23
+ get_global_allowed_permissions,
24
+ )
18
25
  from janito.tools.tool_base import ToolPermissions
26
+
19
27
  current = get_global_allowed_permissions()
20
- new_perms = ToolPermissions(read=enable, write=current.write, execute=current.execute)
28
+ new_perms = ToolPermissions(
29
+ read=enable, write=current.write, execute=current.execute
30
+ )
21
31
  set_global_allowed_permissions(new_perms)
22
32
  # Also update the singleton tools registry permissions
23
33
  import janito.tools
34
+
24
35
  janito.tools.local_tools_adapter.set_allowed_permissions(new_perms)
25
36
 
26
37
  except Exception as e:
27
- shared_console.print(f"[yellow]Warning: Could not update read permissions dynamically: {e}[/yellow]")
38
+ shared_console.print(
39
+ f"[yellow]Warning: Could not update read permissions dynamically: {e}[/yellow]"
40
+ )
28
41
  # Refresh system prompt if agent is available
29
42
  agent = getattr(self.shell_state, "agent", None)
30
43
  if agent:
31
44
  agent.refresh_system_prompt_from_template()
32
45
  # No need to print the system prompt after permission change
33
46
  if enable:
34
- shared_console.print("[green]Read permissions ENABLED. Tools can now read files and data.[/green]")
47
+ shared_console.print(
48
+ "[green]Read permissions ENABLED. Tools can now read files and data.[/green]"
49
+ )
35
50
  else:
36
- shared_console.print("[yellow]Read permissions DISABLED. Tools cannot read files/data.[/yellow]")
51
+ shared_console.print(
52
+ "[yellow]Read permissions DISABLED. Tools cannot read files/data.[/yellow]"
53
+ )
@@ -1,6 +1,7 @@
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 ToolsShellHandler(ShellCmdHandler):
5
6
  help_text = "List available tools"
6
7
 
@@ -27,7 +28,7 @@ class ToolsShellHandler(ShellCmdHandler):
27
28
  perm_groups = {}
28
29
  for tool in tools:
29
30
  inst = tool_instances.get(tool, None)
30
- perms = getattr(inst, 'permissions', None)
31
+ perms = getattr(inst, "permissions", None)
31
32
  if not perms:
32
33
  group = "unknown"
33
34
  else:
@@ -37,6 +38,7 @@ class ToolsShellHandler(ShellCmdHandler):
37
38
 
38
39
  def _print_tools_table(self, perm_groups):
39
40
  from rich.table import Table
41
+
40
42
  table = Table(title="Tools by Permission Class")
41
43
  table.add_column("Permission Type", style="cyan", no_wrap=True)
42
44
  table.add_column("Tools", style="magenta")
@@ -47,27 +49,36 @@ class ToolsShellHandler(ShellCmdHandler):
47
49
  def _find_exec_tools(self, registry):
48
50
  exec_tools = []
49
51
  for tool_instance in registry.get_tools():
50
- perms = getattr(tool_instance, 'permissions', None)
52
+ perms = getattr(tool_instance, "permissions", None)
51
53
  if perms and perms.execute:
52
54
  exec_tools.append(tool_instance.tool_name)
53
55
  return exec_tools
54
56
 
55
57
  def run(self):
58
+ # Check for no_tools_mode in shell_state
59
+ if self.shell_state and getattr(self.shell_state, 'no_tools_mode', False):
60
+ shared_console.print("[yellow]No tools are available in this mode (no tools, no context).[/yellow]")
61
+ return
56
62
  try:
57
63
  import janito.tools # Ensure all tools are registered
58
64
  from janito.tools.permissions import get_global_allowed_permissions
65
+
59
66
  registry = janito.tools.get_local_tools_adapter()
60
67
  tools = registry.list_tools()
61
68
  shared_console.print("Registered tools:")
62
69
  tool_instances = {t.tool_name: t for t in registry.get_tools()}
63
70
  if not tools:
64
- shared_console.print("No tools are enabled under the current permission settings.")
71
+ shared_console.print(
72
+ "No tools are enabled under the current permission settings."
73
+ )
65
74
  return
66
75
  perm_groups = self._group_tools_by_permission(tools, tool_instances)
67
76
  self._print_tools_table(perm_groups)
68
77
  exec_tools = self._find_exec_tools(registry)
69
78
  perms = get_global_allowed_permissions()
70
79
  if not perms.execute and exec_tools:
71
- shared_console.print("[yellow]⚠️ Warning: Execution tools (e.g., commands, code execution) are disabled. Use -x to enable them.[/yellow]")
80
+ shared_console.print(
81
+ "[yellow]⚠️ Warning: Execution tools (e.g., commands, code execution) are disabled. Use -x to enable them.[/yellow]"
82
+ )
72
83
  except Exception as e:
73
84
  shared_console.print(f"[red]Error loading tools: {e}[/red]")
@@ -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 WriteShellHandler(ShellCmdHandler):
5
6
  help_text = "/write on|off: Enable or disable write permissions for tools. Usage: /write on or /write 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
@@ -14,23 +18,36 @@ class WriteShellHandler(ShellCmdHandler):
14
18
  return
15
19
  enable = arg == "on"
16
20
  try:
17
- from janito.tools.permissions import set_global_allowed_permissions, get_global_allowed_permissions
21
+ from janito.tools.permissions import (
22
+ set_global_allowed_permissions,
23
+ get_global_allowed_permissions,
24
+ )
18
25
  from janito.tools.tool_base import ToolPermissions
26
+
19
27
  current = get_global_allowed_permissions()
20
- new_perms = ToolPermissions(read=current.read, write=enable, execute=current.execute)
28
+ new_perms = ToolPermissions(
29
+ read=current.read, write=enable, execute=current.execute
30
+ )
21
31
  set_global_allowed_permissions(new_perms)
22
32
  # Also update the singleton tools registry permissions
23
33
  import janito.tools
34
+
24
35
  janito.tools.local_tools_adapter.set_allowed_permissions(new_perms)
25
36
 
26
37
  except Exception as e:
27
- shared_console.print(f"[yellow]Warning: Could not update write permissions dynamically: {e}[/yellow]")
38
+ shared_console.print(
39
+ f"[yellow]Warning: Could not update write permissions dynamically: {e}[/yellow]"
40
+ )
28
41
  # Refresh system prompt if agent is available
29
42
  agent = getattr(self.shell_state, "agent", None)
30
43
  if agent:
31
44
  agent.refresh_system_prompt_from_template()
32
45
  # No need to print the system prompt after permission change
33
46
  if enable:
34
- shared_console.print("[green]Write permissions ENABLED. Tools can now write files and data.[/green]")
47
+ shared_console.print(
48
+ "[green]Write permissions ENABLED. Tools can now write files and data.[/green]"
49
+ )
35
50
  else:
36
- shared_console.print("[yellow]Write permissions DISABLED. Tools cannot write files/data.[/yellow]")
51
+ shared_console.print(
52
+ "[yellow]Write permissions DISABLED. Tools cannot write files/data.[/yellow]"
53
+ )
@@ -12,7 +12,9 @@ class UserInputHistory:
12
12
  """
13
13
 
14
14
  def __init__(self, history_dir=None):
15
- self.history_dir = history_dir or os.path.join(os.path.expanduser("~"), ".janito", "input_history")
15
+ self.history_dir = history_dir or os.path.join(
16
+ os.path.expanduser("~"), ".janito", "input_history"
17
+ )
16
18
  os.makedirs(self.history_dir, exist_ok=True)
17
19
 
18
20
  def _get_today_file(self):
@@ -38,5 +38,3 @@ def set_role(role):
38
38
  rc = RuntimeConfig()
39
39
  rc.role = role
40
40
  rc.save()
41
-
42
-
@@ -3,6 +3,7 @@ from janito.performance_collector import PerformanceCollector
3
3
  from janito.cli.config import config
4
4
  from janito import __version__ as VERSION
5
5
 
6
+
6
7
  def format_tokens(n, tag=None):
7
8
  if n is None:
8
9
  return "?"
@@ -14,15 +15,20 @@ def format_tokens(n, tag=None):
14
15
  val = f"{n/1000000:.1f}M"
15
16
  return f"<{tag}>{val}</{tag}>" if tag else val
16
17
 
18
+
17
19
  def assemble_first_line(provider_name, model_name, role, agent=None):
18
20
  return f" Janito {VERSION} | Provider: <provider>{provider_name}</provider> | Model: <model>{model_name}</model> | Role: <role>{role}</role>"
19
21
 
22
+
20
23
  def assemble_bindings_line(width, permissions=None):
21
24
  def color_state(state):
22
- return 'on ' if state == "on" else 'off'
25
+ return "on " if state == "on" else "off"
26
+
23
27
  read_state = color_state("on" if getattr(permissions, "read", False) else "off")
24
28
  write_state = color_state("on" if getattr(permissions, "write", False) else "off")
25
- execute_state = color_state("on" if getattr(permissions, "execute", False) else "off")
29
+ execute_state = color_state(
30
+ "on" if getattr(permissions, "execute", False) else "off"
31
+ )
26
32
  return (
27
33
  f" <key-label>CTRL-C</key-label>: Interrupt/Exit | "
28
34
  f"<key-label>F2</key-label>: /restart | "
@@ -30,6 +36,7 @@ def assemble_bindings_line(width, permissions=None):
30
36
  f"<key-label>F12</key-label>: Do It "
31
37
  )
32
38
 
39
+
33
40
  def _get_status(shell_state):
34
41
  _support = getattr(shell_state, "_support", False)
35
42
  _status = getattr(shell_state, "_status", None)
@@ -37,47 +44,46 @@ def _get_status(shell_state):
37
44
  return None
38
45
  if _status == "starting" or _status is None:
39
46
  return _status
40
- live_status = getattr(shell_state, "_live_status", None)
41
- if live_status is not None:
42
- return live_status
47
+
43
48
  return _status
44
49
 
50
+
45
51
  def _get_agent_info(agent):
46
- provider_name = agent.get_provider_name() if hasattr(agent, "get_provider_name") else "?"
52
+ provider_name = (
53
+ agent.get_provider_name() if hasattr(agent, "get_provider_name") else "?"
54
+ )
47
55
  model_name = agent.get_model_name() if hasattr(agent, "get_model_name") else "?"
48
- role = agent.template_vars.get("role", "?") if hasattr(agent, "template_vars") else "?"
56
+ role = (
57
+ agent.template_vars.get("role", "?") if hasattr(agent, "template_vars") else "?"
58
+ )
49
59
  return provider_name, model_name, role
50
60
 
61
+
51
62
  def _get_permissions():
52
63
  try:
53
64
  from janito.tools.permissions import get_global_allowed_permissions
65
+
54
66
  return get_global_allowed_permissions()
55
67
  except Exception:
56
68
  return None
57
69
 
58
- def _get_termweb_status_line(this__status, _port):
59
- if this__status == "online" and _port:
60
- return "\n<> Termweb </>Online"
61
- elif this__status == "starting":
62
- return "\n<> Termweb </>Starting"
63
- elif this__status == "offline":
64
- return "\n<> Termweb </>Offline"
65
- return ""
66
70
 
67
71
  def get_toolbar_func(perf: PerformanceCollector, msg_count: int, shell_state):
68
72
  from prompt_toolkit.application.current import get_app
73
+
69
74
  def get_toolbar():
70
75
  width = get_app().output.get_size().columns
71
76
  agent = getattr(shell_state, "agent", None)
72
77
  this__status = _get_status(shell_state)
73
- provider_name, model_name, role = _get_agent_info(agent) if agent is not None else ("?", "?", "?")
78
+ provider_name, model_name, role = (
79
+ _get_agent_info(agent) if agent is not None else ("?", "?", "?")
80
+ )
74
81
  usage = perf.get_last_request_usage()
75
82
  first_line = assemble_first_line(provider_name, model_name, role, agent=agent)
76
83
  permissions = _get_permissions()
77
84
  bindings_line = assemble_bindings_line(width, permissions)
78
85
  toolbar_text = first_line + "\n" + bindings_line
79
- _port = getattr(shell_state, "_port", None)
80
- toolbar_text += _get_termweb_status_line(this__status, _port)
86
+
81
87
  return HTML(toolbar_text)
82
- return get_toolbar
83
88
 
89
+ return get_toolbar
@@ -32,4 +32,4 @@ def handle_list_models(args, provider_instance):
32
32
  print(f"- {m}")
33
33
  except Exception as e:
34
34
  print(f"Error listing models for provider '{provider_name}': {e}")
35
- sys.exit(0)
35
+ return
@@ -7,3 +7,4 @@ from janito.provider_registry import list_providers
7
7
 
8
8
  def handle_list_providers(args=None):
9
9
  list_providers()
10
+ return
@@ -3,21 +3,29 @@ CLI Command: List available tools
3
3
  """
4
4
 
5
5
 
6
- def _group_tools_by_permission(tools, tool_instances):
6
+ def _group_tools_by_permission(tools, tool_instances, disabled_tools):
7
7
  read_only_tools = []
8
8
  write_only_tools = []
9
9
  read_write_tools = []
10
10
  exec_tools = []
11
11
  import inspect
12
+
12
13
  for tool in tools:
14
+ # Skip disabled tools entirely
15
+ if tool in disabled_tools:
16
+ continue
17
+
13
18
  inst = tool_instances.get(tool, None)
14
19
  param_names = []
15
20
  if inst and hasattr(inst, "run"):
16
21
  sig = inspect.signature(inst.run)
17
22
  param_names = [p for p in sig.parameters if p != "self"]
23
+
18
24
  info = {
19
25
  "name": tool,
20
26
  "params": ", ".join(param_names),
27
+ "tool_name": tool,
28
+ "disabled": False,
21
29
  }
22
30
  perms = getattr(inst, "permissions", None)
23
31
  if perms and perms.execute:
@@ -30,33 +38,54 @@ def _group_tools_by_permission(tools, tool_instances):
30
38
  write_only_tools.append(info)
31
39
  return read_only_tools, write_only_tools, read_write_tools, exec_tools
32
40
 
41
+
33
42
  def _print_tools_table(console, title, tools_info):
34
43
  from rich.table import Table
35
- table = Table(title=title, show_header=True, header_style="bold", show_lines=False, box=None)
44
+
45
+ table = Table(
46
+ title=title, show_header=True, header_style="bold", show_lines=False, box=None
47
+ )
36
48
  table.add_column("Name", style="cyan", no_wrap=True)
37
49
  table.add_column("Parameters", style="yellow")
38
50
  for info in tools_info:
39
51
  table.add_row(info["name"], info["params"] or "-")
40
52
  console.print(table)
41
53
 
54
+
42
55
  def handle_list_tools(args=None):
43
56
  from janito.tools.adapters.local.adapter import LocalToolsAdapter
44
57
  import janito.tools # Ensure all tools are registered
45
58
  from janito.tools.tool_base import ToolPermissions
59
+
46
60
  read = getattr(args, "read", False) if args else False
47
61
  write = getattr(args, "write", False) if args else False
48
62
  execute = getattr(args, "exec", False) if args else False
49
63
  if not (read or write or execute):
50
64
  read = write = execute = True
51
65
  from janito.tools.permissions import set_global_allowed_permissions
52
- set_global_allowed_permissions(ToolPermissions(read=read, write=write, execute=execute))
53
- registry = janito.tools.get_local_tools_adapter()
66
+
67
+ set_global_allowed_permissions(
68
+ ToolPermissions(read=read, write=write, execute=execute)
69
+ )
70
+ # Load disabled tools from config
71
+ from janito.tools.disabled_tools import DisabledToolsState
72
+ from janito.config import config
73
+
74
+ disabled_str = config.get("disabled_tools", "")
75
+ if disabled_str:
76
+ DisabledToolsState.set_disabled_tools(disabled_str)
77
+ disabled_tools = DisabledToolsState.get_disabled_tools()
78
+
79
+ registry = janito.tools.local_tools_adapter
54
80
  tools = registry.list_tools()
55
81
  if tools:
56
82
  from rich.console import Console
83
+
57
84
  console = Console()
58
85
  tool_instances = {t.tool_name: t for t in registry.get_tools()}
59
- read_only_tools, write_only_tools, read_write_tools, exec_tools = _group_tools_by_permission(tools, tool_instances)
86
+ read_only_tools, write_only_tools, read_write_tools, exec_tools = (
87
+ _group_tools_by_permission(tools, tool_instances, disabled_tools)
88
+ )
60
89
  if read_only_tools:
61
90
  _print_tools_table(console, "Read-only tools (-r)", read_only_tools)
62
91
  if write_only_tools:
@@ -67,5 +96,4 @@ def handle_list_tools(args=None):
67
96
  _print_tools_table(console, "Execution tools (-x)", exec_tools)
68
97
  else:
69
98
  print("No tools registered.")
70
- import sys
71
- sys.exit(0)
99
+ return
@@ -35,18 +35,20 @@ def _print_models_table(models, provider_name):
35
35
  row.extend(_build_model_row(m, headers, num_fields))
36
36
  table.add_row(*row)
37
37
  import sys
38
+
38
39
  if sys.stdout.isatty():
39
40
  from rich.console import Console
41
+
40
42
  Console().print(table)
41
43
  else:
42
44
  # ASCII-friendly fallback table when output is redirected
43
45
  print(f"Supported models for provider '{provider_name}'")
44
46
  headers_fallback = [h for h in display_headers]
45
- print(' | '.join(headers_fallback))
47
+ print(" | ".join(headers_fallback))
46
48
  for m in models:
47
- row = [str(m.get('name', ''))]
49
+ row = [str(m.get("name", ""))]
48
50
  row.extend(_build_model_row(m, headers, num_fields))
49
- print(' | '.join(row))
51
+ print(" | ".join(row))
50
52
 
51
53
 
52
54
  def _add_table_columns(table, display_headers):
@@ -49,3 +49,15 @@ def handle_show_config(args):
49
49
  console.print(
50
50
  f" [bold]{pname}[/bold]{' '+sel if sel else ''}: model = [magenta]{eff_model}[/magenta]{extra}"
51
51
  )
52
+
53
+ # Show disabled tools
54
+ from janito.tools.disabled_tools import load_disabled_tools_from_config
55
+
56
+ disabled_tools = load_disabled_tools_from_config()
57
+ if disabled_tools:
58
+ console.print(
59
+ f"\n[bold red]Disabled tools:[/bold red] {', '.join(sorted(disabled_tools))}"
60
+ )
61
+ else:
62
+ console.print("\n[bold green]No tools are disabled[/bold green]")
63
+ return
@@ -14,6 +14,7 @@ import re
14
14
 
15
15
  def _compute_permission_string(args):
16
16
  from janito.tools.tool_base import ToolPermissions
17
+
17
18
  read = getattr(args, "read", False)
18
19
  write = getattr(args, "write", False)
19
20
  execute = getattr(args, "exec", False)
@@ -33,7 +34,7 @@ def _prepare_context(args, agent_role, allowed_permissions):
33
34
  context["role"] = agent_role or "developer"
34
35
  context["profile"] = getattr(args, "profile", None)
35
36
  context["allowed_permissions"] = allowed_permissions
36
- if allowed_permissions and 'x' in allowed_permissions:
37
+ if allowed_permissions and "x" in allowed_permissions:
37
38
  pd = PlatformDiscovery()
38
39
  context["platform"] = pd.get_platform_name()
39
40
  context["python_version"] = pd.get_python_version()
@@ -43,7 +44,8 @@ def _prepare_context(args, agent_role, allowed_permissions):
43
44
 
44
45
  def _load_template(profile, templates_dir):
45
46
  if profile:
46
- template_filename = f"system_prompt_template_{profile}.txt.j2"
47
+ sanitized_profile = re.sub(r"\\s+", "_", profile.strip())
48
+ template_filename = f"system_prompt_template_{sanitized_profile}.txt.j2"
47
49
  template_path = templates_dir / template_filename
48
50
  else:
49
51
  return None, None
@@ -65,8 +67,13 @@ def _load_template(profile, templates_dir):
65
67
  def _print_debug_info(debug_flag, template_filename, allowed_permissions, context):
66
68
  if debug_flag:
67
69
  from rich import print as rich_print
68
- rich_print(f"[bold magenta][DEBUG][/bold magenta] Rendering system prompt template '[cyan]{template_filename}[/cyan]' with allowed_permissions: [yellow]{allowed_permissions}[/yellow]")
69
- rich_print(f"[bold magenta][DEBUG][/bold magenta] Template context: [green]{context}[/green]")
70
+
71
+ rich_print(
72
+ f"[bold magenta][DEBUG][/bold magenta] Rendering system prompt template '[cyan]{template_filename}[/cyan]' with allowed_permissions: [yellow]{allowed_permissions}[/yellow]"
73
+ )
74
+ rich_print(
75
+ f"[bold magenta][DEBUG][/bold magenta] Template context: [green]{context}[/green]"
76
+ )
70
77
 
71
78
 
72
79
  def handle_show_system_prompt(args):
@@ -85,9 +92,12 @@ def handle_show_system_prompt(args):
85
92
 
86
93
  # Debug flag detection
87
94
  import sys
95
+
88
96
  debug_flag = False
89
97
  try:
90
- debug_flag = (hasattr(sys, 'argv') and ('--debug' in sys.argv or '--verbose' in sys.argv or '-v' in sys.argv))
98
+ debug_flag = hasattr(sys, "argv") and (
99
+ "--debug" in sys.argv or "--verbose" in sys.argv or "-v" in sys.argv
100
+ )
91
101
  except Exception:
92
102
  pass
93
103
 
@@ -96,8 +106,10 @@ def handle_show_system_prompt(args):
96
106
  )
97
107
  profile = getattr(args, "profile", None)
98
108
  if not profile:
99
- print("[janito] No profile specified. The main agent runs without a system prompt template.\n"
100
- "Use --profile PROFILE to view a profile-specific system prompt.")
109
+ print(
110
+ "[janito] No profile specified. The main agent runs without a system prompt template.\n"
111
+ "Use --profile PROFILE to view a profile-specific system prompt."
112
+ )
101
113
  return
102
114
 
103
115
  template_filename, template_content = _load_template(profile, templates_dir)
@@ -117,9 +129,11 @@ def handle_show_system_prompt(args):
117
129
 
118
130
  template = Template(template_content)
119
131
  system_prompt = template.render(**context)
120
- system_prompt = re.sub(r'\n{3,}', '\n\n', system_prompt)
132
+ system_prompt = re.sub(r"\n{3,}", "\n\n", system_prompt)
121
133
 
122
- print(f"\n--- System Prompt (resolved, profile: {getattr(args, 'profile', 'main')}) ---\n")
134
+ print(
135
+ f"\n--- System Prompt (resolved, profile: {getattr(args, 'profile', 'main')}) ---\n"
136
+ )
123
137
  print(system_prompt)
124
138
  print("\n-------------------------------\n")
125
139
  if agent_role:
janito/cli/config.py CHANGED
@@ -12,16 +12,3 @@ CONFIG_OPTIONS = {
12
12
  "template": "Template context dictionary for Agent Profile prompt rendering (nested)",
13
13
  "profile": "Agent Profile name (only 'base' is supported)",
14
14
  }
15
-
16
-
17
-
18
- def get__port():
19
- port = config.get("_port")
20
- try:
21
- return int(port)
22
- except Exception:
23
- pass
24
-
25
-
26
- def set__port(port):
27
- config.file_set("_port", int(port))
@@ -1,4 +1,5 @@
1
1
  """Handlers for get-type CLI commands (show_config, list_providers, models, tools)."""
2
+
2
3
  import sys
3
4
 
4
5
  from janito.cli.cli_commands.list_providers import handle_list_providers
@@ -17,6 +18,7 @@ def handle_getter(args, config_mgr=None):
17
18
  provider = getattr(args, "provider", None)
18
19
  if not provider:
19
20
  import sys
21
+
20
22
  print(
21
23
  "Error: No provider selected. Please set a provider using '-p PROVIDER', '--set provider=name', or configure a provider."
22
24
  )
janito/cli/core/runner.py CHANGED
@@ -77,7 +77,7 @@ def prepare_llm_driver_config(args, modifiers):
77
77
  f"Error: Model '{model}' is not available for provider '{provider}'."
78
78
  )
79
79
  # Optionally, print available models if possible
80
- if hasattr(provider_instance, 'get_model_info'):
80
+ if hasattr(provider_instance, "get_model_info"):
81
81
  available_models = [
82
82
  m["name"]
83
83
  for m in provider_instance.get_model_info().values()
@@ -97,7 +97,13 @@ def prepare_llm_driver_config(args, modifiers):
97
97
  return provider, llm_driver_config, agent_role
98
98
 
99
99
 
100
- def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=False, ):
100
+ def handle_runner(
101
+ args,
102
+ provider,
103
+ llm_driver_config,
104
+ agent_role,
105
+ verbose_tools=False,
106
+ ):
101
107
  """
102
108
  Main runner for CLI execution. If exec_enabled is False, disables execution/run tools.
103
109
  """
@@ -107,18 +113,29 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
107
113
  # Patch: disable execution/run tools if not enabled
108
114
  import janito.tools
109
115
  from janito.tools.tool_base import ToolPermissions
116
+
110
117
  read = getattr(args, "read", False)
111
118
  write = getattr(args, "write", False)
112
119
  execute = getattr(args, "exec", False)
113
120
  from janito.tools.permissions import set_global_allowed_permissions
114
121
  from janito.tools.tool_base import ToolPermissions
122
+
115
123
  allowed_permissions = ToolPermissions(read=read, write=write, execute=execute)
116
124
  set_global_allowed_permissions(allowed_permissions)
117
125
  # Store the default permissions for later restoration (e.g., on /restart)
118
126
  from janito.tools.permissions import set_default_allowed_permissions
127
+
119
128
  set_default_allowed_permissions(allowed_permissions)
129
+
130
+ # Load disabled tools from config
131
+ from janito.tools.disabled_tools import load_disabled_tools_from_config
132
+
133
+ load_disabled_tools_from_config()
134
+
120
135
  unrestricted_paths = getattr(args, "unrestricted_paths", False)
121
- adapter = janito.tools.get_local_tools_adapter(workdir=getattr(args, "workdir", None))
136
+ adapter = janito.tools.get_local_tools_adapter(
137
+ workdir=getattr(args, "workdir", None)
138
+ )
122
139
  if unrestricted_paths:
123
140
  # Patch: disable path security enforcement for this adapter instance
124
141
  setattr(adapter, "unrestricted_paths", True)
@@ -128,7 +145,7 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
128
145
  print_verbose_info(
129
146
  "Allowed Tool Permissions",
130
147
  f"read={read}, write={write}, execute={execute}",
131
- style="yellow"
148
+ style="yellow",
132
149
  )
133
150
 
134
151
  provider_instance = ProviderRegistry().get_instance(provider, llm_driver_config)
@@ -146,11 +163,12 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
146
163
  )
147
164
 
148
165
  # DEBUG: Print exec_enabled propagation at runner
149
-
166
+
150
167
  handler = SingleShotPromptHandler(
151
- args, provider_instance, llm_driver_config,
168
+ args,
169
+ provider_instance,
170
+ llm_driver_config,
152
171
  role=agent_role,
153
-
154
172
  allowed_permissions=allowed_permissions,
155
173
  )
156
174
  handler.handle()
@@ -167,7 +185,6 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
167
185
  args=args,
168
186
  verbose_tools=verbose_tools,
169
187
  verbose_agent=getattr(args, "verbose_agent", False),
170
-
171
188
  allowed_permissions=allowed_permissions,
172
189
  )
173
190
  session.run()