janito 2.3.0__py3-none-any.whl → 2.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- janito/__init__.py +6 -6
- janito/_version.py +57 -0
- janito/agent/setup_agent.py +92 -18
- janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +44 -0
- janito/cli/chat_mode/bindings.py +21 -2
- janito/cli/chat_mode/chat_entry.py +2 -3
- janito/cli/chat_mode/prompt_style.py +5 -0
- janito/cli/chat_mode/session.py +80 -94
- janito/cli/chat_mode/session_profile_select.py +80 -0
- janito/cli/chat_mode/shell/autocomplete.py +21 -21
- janito/cli/chat_mode/shell/commands/__init__.py +13 -7
- janito/cli/chat_mode/shell/commands/_priv_check.py +5 -0
- janito/cli/chat_mode/shell/commands/clear.py +12 -12
- janito/cli/chat_mode/shell/commands/conversation_restart.py +30 -0
- janito/cli/chat_mode/shell/commands/execute.py +42 -0
- janito/cli/chat_mode/shell/commands/help.py +6 -3
- janito/cli/chat_mode/shell/commands/model.py +28 -0
- janito/cli/chat_mode/shell/commands/multi.py +51 -51
- janito/cli/chat_mode/shell/commands/read.py +37 -0
- janito/cli/chat_mode/shell/commands/tools.py +45 -18
- janito/cli/chat_mode/shell/commands/write.py +37 -0
- janito/cli/chat_mode/shell/commands.bak.zip +0 -0
- janito/cli/chat_mode/shell/input_history.py +62 -62
- janito/cli/chat_mode/shell/session.bak.zip +0 -0
- janito/cli/chat_mode/toolbar.py +44 -27
- janito/cli/cli_commands/list_models.py +35 -35
- janito/cli/cli_commands/list_providers.py +9 -9
- janito/cli/cli_commands/list_tools.py +86 -53
- janito/cli/cli_commands/model_selection.py +50 -50
- janito/cli/cli_commands/set_api_key.py +19 -19
- janito/cli/cli_commands/show_config.py +51 -51
- janito/cli/cli_commands/show_system_prompt.py +105 -62
- janito/cli/config.py +5 -6
- janito/cli/core/__init__.py +4 -4
- janito/cli/core/event_logger.py +59 -59
- janito/cli/core/runner.py +25 -18
- janito/cli/core/setters.py +10 -1
- janito/cli/core/unsetters.py +54 -54
- janito/cli/main_cli.py +28 -5
- janito/cli/prompt_core.py +18 -2
- janito/cli/prompt_setup.py +56 -0
- janito/cli/single_shot_mode/__init__.py +6 -6
- janito/cli/single_shot_mode/handler.py +14 -73
- janito/cli/verbose_output.py +1 -1
- janito/config.py +5 -5
- janito/config_manager.py +13 -0
- janito/drivers/anthropic/driver.py +113 -113
- janito/drivers/dashscope.bak.zip +0 -0
- janito/drivers/openai/README.md +20 -0
- janito/drivers/openai_responses.bak.zip +0 -0
- janito/event_bus/event.py +2 -2
- janito/formatting_token.py +54 -54
- janito/i18n/__init__.py +35 -35
- janito/i18n/messages.py +23 -23
- janito/i18n/pt.py +46 -47
- janito/llm/README.md +23 -0
- janito/llm/__init__.py +5 -5
- janito/llm/agent.py +507 -443
- janito/llm/driver.py +8 -0
- janito/llm/driver_config_builder.py +34 -34
- janito/llm/driver_input.py +12 -12
- janito/llm/message_parts.py +60 -60
- janito/llm/model.py +38 -38
- janito/llm/provider.py +196 -196
- janito/provider_registry.py +8 -6
- janito/providers/anthropic/model_info.py +22 -22
- janito/providers/anthropic/provider.py +2 -0
- janito/providers/azure_openai/provider.py +3 -0
- janito/providers/dashscope.bak.zip +0 -0
- janito/providers/deepseek/__init__.py +1 -1
- janito/providers/deepseek/model_info.py +16 -16
- janito/providers/deepseek/provider.py +94 -91
- janito/providers/google/provider.py +3 -0
- janito/providers/mistralai/provider.py +3 -0
- janito/providers/openai/provider.py +4 -0
- janito/providers/registry.py +26 -26
- janito/shell.bak.zip +0 -0
- janito/tools/DOCSTRING_STANDARD.txt +33 -0
- janito/tools/README.md +3 -0
- janito/tools/__init__.py +20 -6
- janito/tools/adapters/__init__.py +1 -1
- janito/tools/adapters/local/__init__.py +65 -62
- janito/tools/adapters/local/adapter.py +18 -35
- janito/tools/adapters/local/ask_user.py +101 -102
- janito/tools/adapters/local/copy_file.py +84 -84
- janito/tools/adapters/local/create_directory.py +69 -69
- janito/tools/adapters/local/create_file.py +82 -82
- janito/tools/adapters/local/delete_text_in_file.py +2 -2
- janito/tools/adapters/local/fetch_url.py +97 -97
- janito/tools/adapters/local/find_files.py +139 -138
- janito/tools/adapters/local/get_file_outline/__init__.py +1 -1
- janito/tools/adapters/local/get_file_outline/core.py +117 -117
- janito/tools/adapters/local/get_file_outline/java_outline.py +40 -40
- janito/tools/adapters/local/get_file_outline/markdown_outline.py +14 -14
- janito/tools/adapters/local/get_file_outline/python_outline.py +303 -303
- janito/tools/adapters/local/get_file_outline/python_outline_v2.py +156 -156
- janito/tools/adapters/local/get_file_outline/search_outline.py +33 -33
- janito/tools/adapters/local/move_file.py +2 -2
- janito/tools/adapters/local/open_html_in_browser.py +2 -1
- janito/tools/adapters/local/open_url.py +2 -2
- janito/tools/adapters/local/python_code_run.py +166 -166
- janito/tools/adapters/local/python_command_run.py +164 -164
- janito/tools/adapters/local/python_file_run.py +163 -163
- janito/tools/adapters/local/remove_directory.py +2 -2
- janito/tools/adapters/local/remove_file.py +2 -2
- janito/tools/adapters/local/replace_text_in_file.py +2 -2
- janito/tools/adapters/local/run_bash_command.py +176 -176
- janito/tools/adapters/local/run_powershell_command.py +219 -219
- janito/tools/adapters/local/search_text/__init__.py +1 -1
- janito/tools/adapters/local/search_text/core.py +201 -201
- janito/tools/adapters/local/search_text/pattern_utils.py +73 -73
- janito/tools/adapters/local/search_text/traverse_directory.py +145 -145
- janito/tools/adapters/local/validate_file_syntax/__init__.py +1 -1
- janito/tools/adapters/local/validate_file_syntax/core.py +106 -106
- janito/tools/adapters/local/validate_file_syntax/css_validator.py +35 -35
- janito/tools/adapters/local/validate_file_syntax/html_validator.py +93 -93
- janito/tools/adapters/local/validate_file_syntax/js_validator.py +27 -27
- janito/tools/adapters/local/validate_file_syntax/json_validator.py +6 -6
- janito/tools/adapters/local/validate_file_syntax/markdown_validator.py +109 -109
- janito/tools/adapters/local/validate_file_syntax/ps1_validator.py +32 -32
- janito/tools/adapters/local/validate_file_syntax/python_validator.py +5 -5
- janito/tools/adapters/local/validate_file_syntax/xml_validator.py +11 -11
- janito/tools/adapters/local/validate_file_syntax/yaml_validator.py +6 -6
- janito/tools/adapters/local/view_file.py +168 -167
- janito/tools/inspect_registry.py +17 -17
- janito/tools/outline_file.bak.zip +0 -0
- janito/tools/permissions.py +45 -0
- janito/tools/permissions_parse.py +12 -0
- janito/tools/tool_base.py +118 -105
- janito/tools/tool_events.py +58 -58
- janito/tools/tool_run_exception.py +12 -12
- janito/tools/tool_use_tracker.py +81 -81
- janito/tools/tool_utils.py +43 -45
- janito/tools/tools_adapter.py +25 -20
- janito/tools/tools_schema.py +104 -104
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/METADATA +425 -388
- janito-2.4.0.dist-info/RECORD +195 -0
- janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +0 -13
- janito/agent/templates/profiles/system_prompt_template_main.txt.j2 +0 -37
- janito/cli/chat_mode/shell/commands/edit.py +0 -25
- janito/cli/chat_mode/shell/commands/exec.py +0 -27
- janito/cli/chat_mode/shell/commands/termweb_log.py +0 -92
- janito/cli/termweb_starter.py +0 -122
- janito/termweb/app.py +0 -95
- janito/version.py +0 -4
- janito-2.3.0.dist-info/RECORD +0 -181
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/WHEEL +0 -0
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/entry_points.txt +0 -0
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/licenses/LICENSE +0 -0
- {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/top_level.txt +0 -0
@@ -1,51 +1,51 @@
|
|
1
|
-
from rich.console import Console
|
2
|
-
from rich.pretty import Pretty
|
3
|
-
|
4
|
-
from janito.config import config
|
5
|
-
from janito.cli.config import CONFIG_OPTIONS
|
6
|
-
|
7
|
-
|
8
|
-
def resolve_effective_model(provider_name):
|
9
|
-
# Try provider-specific model, then global model, then provider default
|
10
|
-
provider_cfg = config.get_provider_config(provider_name)
|
11
|
-
model = provider_cfg.get("model") if provider_cfg else None
|
12
|
-
if not model:
|
13
|
-
model = config.get("model")
|
14
|
-
if not model:
|
15
|
-
try:
|
16
|
-
from janito.provider_registry import ProviderRegistry
|
17
|
-
|
18
|
-
provider_class = ProviderRegistry().get_provider(provider_name)
|
19
|
-
model = getattr(provider_class, "DEFAULT_MODEL", None)
|
20
|
-
except Exception:
|
21
|
-
model = None
|
22
|
-
return model
|
23
|
-
|
24
|
-
|
25
|
-
def handle_show_config(args):
|
26
|
-
console = Console()
|
27
|
-
provider = config.get("provider")
|
28
|
-
model = config.get("model")
|
29
|
-
# Show all providers with their effective model
|
30
|
-
from janito.provider_registry import ProviderRegistry
|
31
|
-
|
32
|
-
provider_names = []
|
33
|
-
try:
|
34
|
-
provider_names = ProviderRegistry()._get_provider_names()
|
35
|
-
except Exception:
|
36
|
-
pass
|
37
|
-
console.print("[bold green]Current configuration:[/bold green]")
|
38
|
-
console.print(f"[bold yellow]Current provider:[/bold yellow] {provider!r}\n")
|
39
|
-
if model is not None:
|
40
|
-
console.print(f"[bold yellow]Global model:[/bold yellow] {model!r}\n")
|
41
|
-
if provider_names:
|
42
|
-
console.print("[bold cyan]Provider specific default models:[/bold cyan]")
|
43
|
-
for pname in provider_names:
|
44
|
-
eff_model = resolve_effective_model(pname)
|
45
|
-
prov_cfg = config.get_provider_config(pname)
|
46
|
-
prov_model = prov_cfg.get("model") if prov_cfg else None
|
47
|
-
extra = f" (override)" if prov_model else ""
|
48
|
-
sel = "[default]" if pname == provider else ""
|
49
|
-
console.print(
|
50
|
-
f" [bold]{pname}[/bold]{' '+sel if sel else ''}: model = [magenta]{eff_model}[/magenta]{extra}"
|
51
|
-
)
|
1
|
+
from rich.console import Console
|
2
|
+
from rich.pretty import Pretty
|
3
|
+
|
4
|
+
from janito.config import config
|
5
|
+
from janito.cli.config import CONFIG_OPTIONS
|
6
|
+
|
7
|
+
|
8
|
+
def resolve_effective_model(provider_name):
|
9
|
+
# Try provider-specific model, then global model, then provider default
|
10
|
+
provider_cfg = config.get_provider_config(provider_name)
|
11
|
+
model = provider_cfg.get("model") if provider_cfg else None
|
12
|
+
if not model:
|
13
|
+
model = config.get("model")
|
14
|
+
if not model:
|
15
|
+
try:
|
16
|
+
from janito.provider_registry import ProviderRegistry
|
17
|
+
|
18
|
+
provider_class = ProviderRegistry().get_provider(provider_name)
|
19
|
+
model = getattr(provider_class, "DEFAULT_MODEL", None)
|
20
|
+
except Exception:
|
21
|
+
model = None
|
22
|
+
return model
|
23
|
+
|
24
|
+
|
25
|
+
def handle_show_config(args):
|
26
|
+
console = Console()
|
27
|
+
provider = config.get("provider")
|
28
|
+
model = config.get("model")
|
29
|
+
# Show all providers with their effective model
|
30
|
+
from janito.provider_registry import ProviderRegistry
|
31
|
+
|
32
|
+
provider_names = []
|
33
|
+
try:
|
34
|
+
provider_names = ProviderRegistry()._get_provider_names()
|
35
|
+
except Exception:
|
36
|
+
pass
|
37
|
+
console.print("[bold green]Current configuration:[/bold green]")
|
38
|
+
console.print(f"[bold yellow]Current provider:[/bold yellow] {provider!r}\n")
|
39
|
+
if model is not None:
|
40
|
+
console.print(f"[bold yellow]Global model:[/bold yellow] {model!r}\n")
|
41
|
+
if provider_names:
|
42
|
+
console.print("[bold cyan]Provider specific default models:[/bold cyan]")
|
43
|
+
for pname in provider_names:
|
44
|
+
eff_model = resolve_effective_model(pname)
|
45
|
+
prov_cfg = config.get_provider_config(pname)
|
46
|
+
prov_model = prov_cfg.get("model") if prov_cfg else None
|
47
|
+
extra = f" (override)" if prov_model else ""
|
48
|
+
sel = "[default]" if pname == provider else ""
|
49
|
+
console.print(
|
50
|
+
f" [bold]{pname}[/bold]{' '+sel if sel else ''}: model = [magenta]{eff_model}[/magenta]{extra}"
|
51
|
+
)
|
@@ -1,62 +1,105 @@
|
|
1
|
-
"""
|
2
|
-
CLI Command: Show the resolved system prompt for the main agent (single-shot mode)
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
from
|
8
|
-
from
|
9
|
-
import
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
context["
|
29
|
-
context["
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
1
|
+
"""
|
2
|
+
CLI Command: Show the resolved system prompt for the main agent (single-shot mode)
|
3
|
+
|
4
|
+
Supports --profile to select a profile-specific system prompt template.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from janito.cli.core.runner import prepare_llm_driver_config
|
8
|
+
from janito.platform_discovery import PlatformDiscovery
|
9
|
+
from pathlib import Path
|
10
|
+
from jinja2 import Template
|
11
|
+
import importlib.resources
|
12
|
+
|
13
|
+
|
14
|
+
def handle_show_system_prompt(args):
|
15
|
+
# Collect modifiers as in JanitoCLI
|
16
|
+
from janito.cli.main_cli import MODIFIER_KEYS
|
17
|
+
|
18
|
+
modifiers = {
|
19
|
+
k: getattr(args, k) for k in MODIFIER_KEYS if getattr(args, k, None) is not None
|
20
|
+
}
|
21
|
+
provider, llm_driver_config, agent_role = prepare_llm_driver_config(args, modifiers)
|
22
|
+
if provider is None or llm_driver_config is None:
|
23
|
+
print("Error: Could not resolve provider or LLM driver config.")
|
24
|
+
return
|
25
|
+
|
26
|
+
# Prepare context for Jinja2 rendering
|
27
|
+
context = {}
|
28
|
+
context["role"] = agent_role or "developer"
|
29
|
+
context["profile"] = getattr(args, "profile", None)
|
30
|
+
# Compute allowed_permissions from CLI args (as in agent setup)
|
31
|
+
from janito.tools.tool_base import ToolPermissions
|
32
|
+
read = getattr(args, "read", False)
|
33
|
+
write = getattr(args, "write", False)
|
34
|
+
execute = getattr(args, "exec", False)
|
35
|
+
allowed = ToolPermissions(read=read, write=write, execute=execute)
|
36
|
+
perm_str = ""
|
37
|
+
if allowed.read:
|
38
|
+
perm_str += "r"
|
39
|
+
if allowed.write:
|
40
|
+
perm_str += "w"
|
41
|
+
if allowed.execute:
|
42
|
+
perm_str += "x"
|
43
|
+
allowed_permissions = perm_str or None
|
44
|
+
context["allowed_permissions"] = allowed_permissions
|
45
|
+
# DEBUG: Show permissions/context before rendering
|
46
|
+
from rich import print as rich_print
|
47
|
+
debug_flag = False
|
48
|
+
import sys
|
49
|
+
try:
|
50
|
+
debug_flag = (hasattr(sys, 'argv') and ('--debug' in sys.argv or '--verbose' in sys.argv or '-v' in sys.argv))
|
51
|
+
except Exception:
|
52
|
+
pass
|
53
|
+
if debug_flag:
|
54
|
+
rich_print(f"[bold magenta][DEBUG][/bold magenta] Rendering system prompt template '[cyan]{template_filename}[/cyan]' with allowed_permissions: [yellow]{allowed_permissions}[/yellow]")
|
55
|
+
rich_print(f"[bold magenta][DEBUG][/bold magenta] Template context: [green]{context}[/green]")
|
56
|
+
if allowed_permissions and 'x' in allowed_permissions:
|
57
|
+
pd = PlatformDiscovery()
|
58
|
+
context["platform"] = pd.get_platform_name()
|
59
|
+
context["python_version"] = pd.get_python_version()
|
60
|
+
context["shell_info"] = pd.detect_shell()
|
61
|
+
|
62
|
+
# Locate and load the system prompt template
|
63
|
+
templates_dir = (
|
64
|
+
Path(__file__).parent.parent.parent / "agent" / "templates" / "profiles"
|
65
|
+
)
|
66
|
+
profile = getattr(args, "profile", None)
|
67
|
+
if profile:
|
68
|
+
template_filename = f"system_prompt_template_{profile}.txt.j2"
|
69
|
+
template_path = templates_dir / template_filename
|
70
|
+
else:
|
71
|
+
# No profile specified means the main agent has no dedicated system prompt template.
|
72
|
+
print("[janito] No profile specified. The main agent runs without a system prompt template.\n"
|
73
|
+
"Use --profile PROFILE to view a profile-specific system prompt.")
|
74
|
+
return
|
75
|
+
template_content = None
|
76
|
+
if template_path and template_path.exists():
|
77
|
+
with open(template_path, "r", encoding="utf-8") as file:
|
78
|
+
template_content = file.read()
|
79
|
+
else:
|
80
|
+
# Try package import fallback
|
81
|
+
try:
|
82
|
+
with importlib.resources.files("janito.agent.templates.profiles").joinpath(
|
83
|
+
template_filename
|
84
|
+
).open("r", encoding="utf-8") as file:
|
85
|
+
template_content = file.read()
|
86
|
+
except (FileNotFoundError, ModuleNotFoundError, AttributeError):
|
87
|
+
if profile:
|
88
|
+
raise FileNotFoundError(
|
89
|
+
f"[janito] Could not find profile-specific template '{template_filename}' in {template_path} nor in janito.agent.templates.profiles package."
|
90
|
+
)
|
91
|
+
else:
|
92
|
+
print(
|
93
|
+
f"[janito] Could not find {template_filename} in {template_path} nor in janito.agent.templates.profiles package."
|
94
|
+
)
|
95
|
+
print("No system prompt is set or resolved for this configuration.")
|
96
|
+
return
|
97
|
+
|
98
|
+
template = Template(template_content)
|
99
|
+
system_prompt = template.render(**context)
|
100
|
+
|
101
|
+
print(f"\n--- System Prompt (resolved, profile: {getattr(args, 'profile', 'main')}) ---\n")
|
102
|
+
print(system_prompt)
|
103
|
+
print("\n-------------------------------\n")
|
104
|
+
if agent_role:
|
105
|
+
print(f"[Role: {agent_role}]")
|
janito/cli/config.py
CHANGED
@@ -13,16 +13,15 @@ CONFIG_OPTIONS = {
|
|
13
13
|
"profile": "Agent Profile name (only 'base' is supported)",
|
14
14
|
}
|
15
15
|
|
16
|
-
DEFAULT_TERMWEB_PORT = 8088
|
17
16
|
|
18
17
|
|
19
|
-
def
|
20
|
-
port = config.get("
|
18
|
+
def get__port():
|
19
|
+
port = config.get("_port")
|
21
20
|
try:
|
22
21
|
return int(port)
|
23
22
|
except Exception:
|
24
|
-
|
23
|
+
pass
|
25
24
|
|
26
25
|
|
27
|
-
def
|
28
|
-
config.file_set("
|
26
|
+
def set__port(port):
|
27
|
+
config.file_set("_port", int(port))
|
janito/cli/core/__init__.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"""
|
2
|
-
Core logic, handler classes, and utilities for the main Janito CLI orchestration and sub-command processing.
|
3
|
-
Contains modules for setters, getters, event logger, and runner pipelines.
|
4
|
-
"""
|
1
|
+
"""
|
2
|
+
Core logic, handler classes, and utilities for the main Janito CLI orchestration and sub-command processing.
|
3
|
+
Contains modules for setters, getters, event logger, and runner pipelines.
|
4
|
+
"""
|
janito/cli/core/event_logger.py
CHANGED
@@ -1,59 +1,59 @@
|
|
1
|
-
"""Stub implementation of EventLogger for the CLI event logging system."""
|
2
|
-
|
3
|
-
|
4
|
-
class EventLogger:
|
5
|
-
def __init__(self, debug=False):
|
6
|
-
self.debug = debug
|
7
|
-
|
8
|
-
def subscribe(self, event_name, callback):
|
9
|
-
if self.debug:
|
10
|
-
pass # Add debug subscribe output if needed
|
11
|
-
# No real subscription logic
|
12
|
-
|
13
|
-
def submit(self, event_name, payload=None):
|
14
|
-
if self.debug:
|
15
|
-
pass # Add debug submit output if needed
|
16
|
-
# No real submission logic
|
17
|
-
|
18
|
-
|
19
|
-
def setup_event_logger(args):
|
20
|
-
debug = getattr(args, "event_debug", False)
|
21
|
-
event_logger = EventLogger(debug=debug)
|
22
|
-
print("[EventLog] Event logger is now active (stub implementation)")
|
23
|
-
return event_logger
|
24
|
-
|
25
|
-
|
26
|
-
def setup_event_logger_if_needed(args):
|
27
|
-
if getattr(args, "event_log", False):
|
28
|
-
print("[EventLog] Setting up event logger with system bus...")
|
29
|
-
event_logger = setup_event_logger(args)
|
30
|
-
from janito.event_bus import event_bus
|
31
|
-
|
32
|
-
def event_logger_handler(event):
|
33
|
-
from janito.cli.console import shared_console
|
34
|
-
from rich.pretty import Pretty
|
35
|
-
from datetime import datetime
|
36
|
-
|
37
|
-
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
38
|
-
shared_console.print(
|
39
|
-
f"[EventLog] [dim]{timestamp}[/] [bold green]{event.__class__.__name__}[/] | [cyan]{getattr(event, 'category', '')}[/]"
|
40
|
-
)
|
41
|
-
shared_console.print(Pretty(event, expand_all=True))
|
42
|
-
shared_console.file.flush()
|
43
|
-
|
44
|
-
from janito.event_bus.event import Event
|
45
|
-
|
46
|
-
event_bus.subscribe(Event, event_logger_handler)
|
47
|
-
|
48
|
-
|
49
|
-
def inject_debug_event_bus_if_needed(args):
|
50
|
-
if getattr(args, "event_debug", False):
|
51
|
-
from janito.event_bus import event_bus
|
52
|
-
|
53
|
-
orig_publish = event_bus.publish
|
54
|
-
|
55
|
-
def debug_publish(event):
|
56
|
-
# You can enrich here if needed
|
57
|
-
return orig_publish(event)
|
58
|
-
|
59
|
-
event_bus.publish = debug_publish
|
1
|
+
"""Stub implementation of EventLogger for the CLI event logging system."""
|
2
|
+
|
3
|
+
|
4
|
+
class EventLogger:
|
5
|
+
def __init__(self, debug=False):
|
6
|
+
self.debug = debug
|
7
|
+
|
8
|
+
def subscribe(self, event_name, callback):
|
9
|
+
if self.debug:
|
10
|
+
pass # Add debug subscribe output if needed
|
11
|
+
# No real subscription logic
|
12
|
+
|
13
|
+
def submit(self, event_name, payload=None):
|
14
|
+
if self.debug:
|
15
|
+
pass # Add debug submit output if needed
|
16
|
+
# No real submission logic
|
17
|
+
|
18
|
+
|
19
|
+
def setup_event_logger(args):
|
20
|
+
debug = getattr(args, "event_debug", False)
|
21
|
+
event_logger = EventLogger(debug=debug)
|
22
|
+
print("[EventLog] Event logger is now active (stub implementation)")
|
23
|
+
return event_logger
|
24
|
+
|
25
|
+
|
26
|
+
def setup_event_logger_if_needed(args):
|
27
|
+
if getattr(args, "event_log", False):
|
28
|
+
print("[EventLog] Setting up event logger with system bus...")
|
29
|
+
event_logger = setup_event_logger(args)
|
30
|
+
from janito.event_bus import event_bus
|
31
|
+
|
32
|
+
def event_logger_handler(event):
|
33
|
+
from janito.cli.console import shared_console
|
34
|
+
from rich.pretty import Pretty
|
35
|
+
from datetime import datetime
|
36
|
+
|
37
|
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
38
|
+
shared_console.print(
|
39
|
+
f"[EventLog] [dim]{timestamp}[/] [bold green]{event.__class__.__name__}[/] | [cyan]{getattr(event, 'category', '')}[/]"
|
40
|
+
)
|
41
|
+
shared_console.print(Pretty(event, expand_all=True))
|
42
|
+
shared_console.file.flush()
|
43
|
+
|
44
|
+
from janito.event_bus.event import Event
|
45
|
+
|
46
|
+
event_bus.subscribe(Event, event_logger_handler)
|
47
|
+
|
48
|
+
|
49
|
+
def inject_debug_event_bus_if_needed(args):
|
50
|
+
if getattr(args, "event_debug", False):
|
51
|
+
from janito.event_bus import event_bus
|
52
|
+
|
53
|
+
orig_publish = event_bus.publish
|
54
|
+
|
55
|
+
def debug_publish(event):
|
56
|
+
# You can enrich here if needed
|
57
|
+
return orig_publish(event)
|
58
|
+
|
59
|
+
event_bus.publish = debug_publish
|
janito/cli/core/runner.py
CHANGED
@@ -92,7 +92,7 @@ def prepare_llm_driver_config(args, modifiers):
|
|
92
92
|
llm_driver_config = LLMDriverConfig(**driver_config_data)
|
93
93
|
if getattr(llm_driver_config, "verbose_api", None):
|
94
94
|
pass
|
95
|
-
agent_role = modifiers.get("role", "
|
95
|
+
agent_role = modifiers.get("role", "developer")
|
96
96
|
return provider, llm_driver_config, agent_role
|
97
97
|
|
98
98
|
|
@@ -105,23 +105,26 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
|
|
105
105
|
|
106
106
|
# Patch: disable execution/run tools if not enabled
|
107
107
|
import janito.tools
|
108
|
+
from janito.tools.tool_base import ToolPermissions
|
109
|
+
read = getattr(args, "read", False)
|
110
|
+
write = getattr(args, "write", False)
|
111
|
+
execute = exec_enabled
|
112
|
+
from janito.tools.permissions import set_global_allowed_permissions
|
113
|
+
from janito.tools.tool_base import ToolPermissions
|
114
|
+
allowed_permissions = ToolPermissions(read=read, write=write, execute=execute)
|
115
|
+
set_global_allowed_permissions(allowed_permissions)
|
116
|
+
# Store the default permissions for later restoration (e.g., on /restart)
|
117
|
+
from janito.tools.permissions import set_default_allowed_permissions
|
118
|
+
set_default_allowed_permissions(allowed_permissions)
|
108
119
|
adapter = janito.tools.get_local_tools_adapter(workdir=getattr(args, "workdir", None))
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
from janito.tools.adapters.local import PythonCodeRunTool, PythonCommandRunTool, PythonFileRunTool, RunBashCommandTool, RunPowershellCommandTool
|
118
|
-
for tool_cls in [PythonCodeRunTool, PythonCommandRunTool, PythonFileRunTool, RunBashCommandTool, RunPowershellCommandTool]:
|
119
|
-
try:
|
120
|
-
adapter.register_tool(tool_cls)
|
121
|
-
except Exception:
|
122
|
-
pass # Already registered or error
|
123
|
-
except Exception:
|
124
|
-
pass
|
120
|
+
|
121
|
+
# Print allowed permissions in verbose mode
|
122
|
+
if getattr(args, "verbose", False):
|
123
|
+
print_verbose_info(
|
124
|
+
"Allowed Tool Permissions",
|
125
|
+
f"read={read}, write={write}, execute={execute}",
|
126
|
+
style="yellow"
|
127
|
+
)
|
125
128
|
|
126
129
|
provider_instance = ProviderRegistry().get_instance(provider, llm_driver_config)
|
127
130
|
if provider_instance is None:
|
@@ -140,7 +143,10 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
|
|
140
143
|
# DEBUG: Print exec_enabled propagation at runner
|
141
144
|
|
142
145
|
handler = SingleShotPromptHandler(
|
143
|
-
args, provider_instance, llm_driver_config,
|
146
|
+
args, provider_instance, llm_driver_config,
|
147
|
+
role=agent_role,
|
148
|
+
exec_enabled=exec_enabled,
|
149
|
+
allowed_permissions=allowed_permissions,
|
144
150
|
)
|
145
151
|
handler.handle()
|
146
152
|
else:
|
@@ -157,6 +163,7 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
|
|
157
163
|
verbose_tools=verbose_tools,
|
158
164
|
verbose_agent=getattr(args, "verbose_agent", False),
|
159
165
|
exec_enabled=exec_enabled,
|
166
|
+
allowed_permissions=allowed_permissions,
|
160
167
|
)
|
161
168
|
session.run()
|
162
169
|
|
janito/cli/core/setters.py
CHANGED
@@ -43,8 +43,17 @@ def handle_set(args, config_mgr=None):
|
|
43
43
|
return True
|
44
44
|
if ".max_tokens" in key or ".base_url" in key:
|
45
45
|
return _handle_set_provider_level_setting(key, value)
|
46
|
+
# Tool permissions support: janito set tool_permissions=rwx
|
47
|
+
if key == "tool_permissions":
|
48
|
+
from janito.tools.permissions_parse import parse_permissions_string
|
49
|
+
from janito.tools.permissions import set_global_allowed_permissions
|
50
|
+
perms = parse_permissions_string(value)
|
51
|
+
global_config.file_set("tool_permissions", value)
|
52
|
+
set_global_allowed_permissions(perms)
|
53
|
+
print(f"Tool permissions set to '{value}' (parsed: {perms})")
|
54
|
+
return True
|
46
55
|
print(
|
47
|
-
f"Error: Unknown config key '{key}'. Supported: provider, model, <provider>.model, max_tokens, base_url, azure_deployment_name, <provider>.max_tokens, <provider>.base_url, <provider>.<model>.max_tokens, <provider>.<model>.base_url"
|
56
|
+
f"Error: Unknown config key '{key}'. Supported: provider, model, <provider>.model, max_tokens, base_url, azure_deployment_name, <provider>.max_tokens, <provider>.base_url, <provider>.<model>.max_tokens, <provider>.<model>.base_url, tool_permissions"
|
48
57
|
)
|
49
58
|
return True
|
50
59
|
except Exception as e:
|
janito/cli/core/unsetters.py
CHANGED
@@ -1,54 +1,54 @@
|
|
1
|
-
from janito.config import config as global_config
|
2
|
-
|
3
|
-
|
4
|
-
def handle_unset(args):
|
5
|
-
unset_arg = getattr(args, "unset", None)
|
6
|
-
if not unset_arg:
|
7
|
-
return False
|
8
|
-
key = unset_arg.strip().replace("-", "_")
|
9
|
-
if "." in key:
|
10
|
-
# Provider or model-specific keys
|
11
|
-
parts = key.split(".")
|
12
|
-
if len(parts) == 2:
|
13
|
-
provider, subkey = parts
|
14
|
-
current_val = (
|
15
|
-
global_config.file_config.get("providers", {})
|
16
|
-
.get(provider, {})
|
17
|
-
.get(subkey)
|
18
|
-
)
|
19
|
-
if current_val is not None:
|
20
|
-
del global_config.file_config["providers"][provider][subkey]
|
21
|
-
global_config.save()
|
22
|
-
print(f"{key}={current_val} was removed.")
|
23
|
-
return True
|
24
|
-
elif len(parts) == 3:
|
25
|
-
provider, model, subkey = parts
|
26
|
-
model_conf = (
|
27
|
-
global_config.file_config.get("providers", {})
|
28
|
-
.get(provider, {})
|
29
|
-
.get("models", {})
|
30
|
-
.get(model, {})
|
31
|
-
)
|
32
|
-
current_val = model_conf.get(subkey)
|
33
|
-
if current_val is not None:
|
34
|
-
del global_config.file_config["providers"][provider]["models"][model][
|
35
|
-
subkey
|
36
|
-
]
|
37
|
-
global_config.save()
|
38
|
-
print(f"{key}={current_val} was removed.")
|
39
|
-
return True
|
40
|
-
else:
|
41
|
-
current_val = global_config.file_config.get(key)
|
42
|
-
if current_val is not None:
|
43
|
-
del global_config.file_config[key]
|
44
|
-
global_config.save()
|
45
|
-
print(f"{key}={current_val} was removed.")
|
46
|
-
return True
|
47
|
-
if "=" in unset_arg:
|
48
|
-
provided_key = unset_arg.split("=")[0].strip()
|
49
|
-
print(
|
50
|
-
f"Error: --unset expected a key, not key=value. Did you mean: --unset {provided_key}?"
|
51
|
-
)
|
52
|
-
else:
|
53
|
-
print(f"Error: no value set for {key} (cannot remove)")
|
54
|
-
return True
|
1
|
+
from janito.config import config as global_config
|
2
|
+
|
3
|
+
|
4
|
+
def handle_unset(args):
|
5
|
+
unset_arg = getattr(args, "unset", None)
|
6
|
+
if not unset_arg:
|
7
|
+
return False
|
8
|
+
key = unset_arg.strip().replace("-", "_")
|
9
|
+
if "." in key:
|
10
|
+
# Provider or model-specific keys
|
11
|
+
parts = key.split(".")
|
12
|
+
if len(parts) == 2:
|
13
|
+
provider, subkey = parts
|
14
|
+
current_val = (
|
15
|
+
global_config.file_config.get("providers", {})
|
16
|
+
.get(provider, {})
|
17
|
+
.get(subkey)
|
18
|
+
)
|
19
|
+
if current_val is not None:
|
20
|
+
del global_config.file_config["providers"][provider][subkey]
|
21
|
+
global_config.save()
|
22
|
+
print(f"{key}={current_val} was removed.")
|
23
|
+
return True
|
24
|
+
elif len(parts) == 3:
|
25
|
+
provider, model, subkey = parts
|
26
|
+
model_conf = (
|
27
|
+
global_config.file_config.get("providers", {})
|
28
|
+
.get(provider, {})
|
29
|
+
.get("models", {})
|
30
|
+
.get(model, {})
|
31
|
+
)
|
32
|
+
current_val = model_conf.get(subkey)
|
33
|
+
if current_val is not None:
|
34
|
+
del global_config.file_config["providers"][provider]["models"][model][
|
35
|
+
subkey
|
36
|
+
]
|
37
|
+
global_config.save()
|
38
|
+
print(f"{key}={current_val} was removed.")
|
39
|
+
return True
|
40
|
+
else:
|
41
|
+
current_val = global_config.file_config.get(key)
|
42
|
+
if current_val is not None:
|
43
|
+
del global_config.file_config[key]
|
44
|
+
global_config.save()
|
45
|
+
print(f"{key}={current_val} was removed.")
|
46
|
+
return True
|
47
|
+
if "=" in unset_arg:
|
48
|
+
provided_key = unset_arg.split("=")[0].strip()
|
49
|
+
print(
|
50
|
+
f"Error: --unset expected a key, not key=value. Did you mean: --unset {provided_key}?"
|
51
|
+
)
|
52
|
+
else:
|
53
|
+
print(f"Error: no value set for {key} (cannot remove)")
|
54
|
+
return True
|