janito 2.7.0__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 +0 -1
- janito/__main__.py +0 -1
- janito/_version.py +0 -3
- janito/agent/setup_agent.py +77 -10
- janito/agent/templates/profiles/{system_prompt_template_plain_software_developer.txt.j2 → system_prompt_template_Developer_with_Python_Tools.txt.j2} +5 -1
- janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +3 -12
- janito/cli/__init__.py +0 -1
- janito/cli/chat_mode/bindings.py +1 -1
- janito/cli/chat_mode/chat_entry.py +0 -2
- janito/cli/chat_mode/prompt_style.py +0 -3
- janito/cli/chat_mode/script_runner.py +9 -5
- 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 +14 -5
- janito/cli/verbose_output.py +5 -1
- janito/config_manager.py +4 -0
- janito/drivers/azure_openai/driver.py +27 -30
- janito/drivers/openai/driver.py +52 -36
- janito/formatting_token.py +12 -4
- janito/llm/agent.py +15 -6
- janito/llm/driver.py +1 -0
- janito/provider_registry.py +31 -70
- janito/providers/__init__.py +1 -0
- janito/providers/anthropic/model_info.py +0 -1
- janito/providers/anthropic/provider.py +9 -14
- 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/provider.py +11 -4
- janito/providers/openai/model_info.py +0 -1
- janito/providers/openai/provider.py +6 -7
- janito/tools/__init__.py +2 -0
- janito/tools/adapters/local/__init__.py +2 -1
- 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 +1 -0
- 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 +19 -4
- 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.7.0.dist-info → janito-2.8.0.dist-info}/METADATA +4 -12
- 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 -21
- janito-2.7.0.dist-info/RECORD +0 -202
- /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.7.0.dist-info → janito-2.8.0.dist-info}/WHEEL +0 -0
- {janito-2.7.0.dist-info → janito-2.8.0.dist-info}/entry_points.txt +0 -0
- {janito-2.7.0.dist-info → janito-2.8.0.dist-info}/licenses/LICENSE +0 -0
- {janito-2.7.0.dist-info → janito-2.8.0.dist-info}/top_level.txt +0 -0
janito/cli/chat_mode/toolbar.py
CHANGED
@@ -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
|
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(
|
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
|
-
|
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 =
|
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 =
|
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 =
|
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
|
-
|
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
|
@@ -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
|
-
|
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
|
-
|
53
|
-
|
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 =
|
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
|
-
|
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(
|
47
|
+
print(" | ".join(headers_fallback))
|
46
48
|
for m in models:
|
47
|
-
row = [str(m.get(
|
49
|
+
row = [str(m.get("name", ""))]
|
48
50
|
row.extend(_build_model_row(m, headers, num_fields))
|
49
|
-
print(
|
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
|
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
|
-
|
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
|
-
|
69
|
-
rich_print(
|
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 =
|
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(
|
100
|
-
|
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
|
132
|
+
system_prompt = re.sub(r"\n{3,}", "\n\n", system_prompt)
|
121
133
|
|
122
|
-
print(
|
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))
|
janito/cli/core/getters.py
CHANGED
@@ -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,
|
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(
|
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(
|
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,
|
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()
|
janito/cli/core/setters.py
CHANGED
@@ -27,25 +27,24 @@ def handle_set(args, config_mgr=None):
|
|
27
27
|
print(f"Error parsing --set value: {e}")
|
28
28
|
return True
|
29
29
|
|
30
|
+
|
30
31
|
def _validate_set_arg_format(set_arg):
|
31
32
|
if "=" not in set_arg:
|
32
|
-
print(
|
33
|
-
"Error: --set requires KEY=VALUE (e.g., --set provider=provider_name)."
|
34
|
-
)
|
33
|
+
print("Error: --set requires KEY=VALUE (e.g., --set provider=provider_name).")
|
35
34
|
return False
|
36
35
|
return True
|
37
36
|
|
37
|
+
|
38
38
|
def _parse_set_arg(set_arg):
|
39
39
|
key, value = set_arg.split("=", 1)
|
40
40
|
return key.strip(), value.strip()
|
41
41
|
|
42
|
+
|
42
43
|
def _dispatch_set_key(key, value):
|
43
44
|
if key == "provider":
|
44
45
|
return _handle_set_config_provider(value)
|
45
46
|
if key == "model":
|
46
47
|
return _handle_set_global_model(value)
|
47
|
-
if "." in key and key.endswith(".model"):
|
48
|
-
return _handle_set_provider_model(key, value)
|
49
48
|
if key == "max_tokens":
|
50
49
|
return _handle_set_max_tokens(value)
|
51
50
|
if key == "base_url":
|
@@ -54,18 +53,24 @@ def _dispatch_set_key(key, value):
|
|
54
53
|
global_config.file_set("azure_deployment_name", value)
|
55
54
|
print(f"Azure deployment name set to '{value}'.")
|
56
55
|
return True
|
57
|
-
if ".max_tokens" in key or ".base_url" in key:
|
58
|
-
return _handle_set_provider_level_setting(key, value)
|
59
56
|
if key == "tool_permissions":
|
60
57
|
from janito.tools.permissions_parse import parse_permissions_string
|
61
58
|
from janito.tools.permissions import set_global_allowed_permissions
|
59
|
+
|
62
60
|
perms = parse_permissions_string(value)
|
63
61
|
global_config.file_set("tool_permissions", value)
|
64
62
|
set_global_allowed_permissions(perms)
|
65
63
|
print(f"Tool permissions set to '{value}' (parsed: {perms})")
|
66
64
|
return True
|
65
|
+
if key == "disabled_tools":
|
66
|
+
from janito.tools.disabled_tools import set_disabled_tools
|
67
|
+
|
68
|
+
set_disabled_tools(value)
|
69
|
+
global_config.file_set("disabled_tools", value)
|
70
|
+
print(f"Disabled tools set to '{value}'")
|
71
|
+
return True
|
67
72
|
print(
|
68
|
-
f"Error: Unknown config key '{key}'. Supported: provider, model,
|
73
|
+
f"Error: Unknown config key '{key}'. Supported: provider, model, max_tokens, base_url, azure_deployment_name, tool_permissions, disabled_tools"
|
69
74
|
)
|
70
75
|
return True
|
71
76
|
|
@@ -87,48 +92,6 @@ def _handle_set_base_url(value):
|
|
87
92
|
return True
|
88
93
|
|
89
94
|
|
90
|
-
def _handle_set_provider_level_setting(key, value):
|
91
|
-
parts = key.split(".")
|
92
|
-
if len(parts) == 2:
|
93
|
-
provider, par_key = parts
|
94
|
-
if par_key == "max_tokens":
|
95
|
-
try:
|
96
|
-
ival = int(value)
|
97
|
-
except Exception:
|
98
|
-
print("Error: max_tokens must be set to an integer value.")
|
99
|
-
return True
|
100
|
-
global_config.set_provider_config(provider, "max_tokens", ival)
|
101
|
-
print(f"max_tokens for provider '{provider}' set to {ival}.")
|
102
|
-
return True
|
103
|
-
if par_key == "base_url":
|
104
|
-
global_config.set_provider_config(provider, "base_url", value)
|
105
|
-
print(f"base_url for provider '{provider}' set to {value}.")
|
106
|
-
return True
|
107
|
-
elif len(parts) == 3:
|
108
|
-
provider, model, mk = parts
|
109
|
-
if mk == "max_tokens":
|
110
|
-
try:
|
111
|
-
ival = int(value)
|
112
|
-
except Exception:
|
113
|
-
print("Error: max_tokens must be set to an integer value.")
|
114
|
-
return True
|
115
|
-
global_config.set_provider_model_config(provider, model, "max_tokens", ival)
|
116
|
-
print(
|
117
|
-
f"max_tokens for provider '{provider}', model '{model}' set to {ival}."
|
118
|
-
)
|
119
|
-
return True
|
120
|
-
if mk == "base_url":
|
121
|
-
global_config.set_provider_model_config(provider, model, "base_url", value)
|
122
|
-
print(
|
123
|
-
f"base_url for provider '{provider}', model '{model}' set to {value}."
|
124
|
-
)
|
125
|
-
return True
|
126
|
-
print(
|
127
|
-
f"Error: Unknown config key '{key}'. Supported: provider, model, <provider>.model, max_tokens, base_url, <provider>.max_tokens, <provider>.base_url, <provider>.<model>.max_tokens, <provider>.<model>.base_url"
|
128
|
-
)
|
129
|
-
return True
|
130
|
-
|
131
|
-
|
132
95
|
def _handle_set_config_provider(value):
|
133
96
|
try:
|
134
97
|
supported = ProviderRegistry().get_provider(value)
|
@@ -144,32 +107,6 @@ def _handle_set_config_provider(value):
|
|
144
107
|
return True
|
145
108
|
|
146
109
|
|
147
|
-
def _handle_set_provider_model(key, value):
|
148
|
-
provider_name, suffix = key.rsplit(".", 1)
|
149
|
-
if suffix != "model":
|
150
|
-
print(
|
151
|
-
f"Error: Only <provider>.model is supported for provider-specific model override. Not: '{key}'"
|
152
|
-
)
|
153
|
-
return True
|
154
|
-
try:
|
155
|
-
provider_cls = ProviderRegistry().get_provider(provider_name)
|
156
|
-
provider_instance = provider_cls()
|
157
|
-
except Exception:
|
158
|
-
print(
|
159
|
-
f"Error: Provider '{provider_name}' is not supported. Run '--list-providers' to see the supported list."
|
160
|
-
)
|
161
|
-
return True
|
162
|
-
model_info = provider_instance.get_model_info(value)
|
163
|
-
if not model_info:
|
164
|
-
print(
|
165
|
-
f"Error: Model '{value}' is not defined for provider '{provider_name}'. Run '-p {provider_name} -l' to see models."
|
166
|
-
)
|
167
|
-
return True
|
168
|
-
global_config.set_provider_config(provider_name, "model", value)
|
169
|
-
print(f"Default model for provider '{provider_name}' set to '{value}'.")
|
170
|
-
return True
|
171
|
-
|
172
|
-
|
173
110
|
def _handle_set_global_model(value):
|
174
111
|
# Try to validate model choice (against current provider if possible)
|
175
112
|
provider_name = global_config.get("provider")
|