janito 1.14.3__py3-none-any.whl → 2.0.1__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 -1
- janito/__main__.py +1 -1
- janito/agent/setup_agent.py +139 -0
- janito/agent/templates/profiles/{system_prompt_template_base.txt.j2 → system_prompt_template_main.txt.j2} +1 -1
- janito/cli/__init__.py +9 -0
- janito/cli/chat_mode/bindings.py +37 -0
- janito/cli/chat_mode/chat_entry.py +23 -0
- janito/cli/chat_mode/prompt_style.py +19 -0
- janito/cli/chat_mode/session.py +272 -0
- janito/{shell/prompt/completer.py → cli/chat_mode/shell/autocomplete.py} +7 -6
- janito/cli/chat_mode/shell/commands/__init__.py +55 -0
- janito/cli/chat_mode/shell/commands/base.py +9 -0
- janito/cli/chat_mode/shell/commands/clear.py +12 -0
- janito/{shell → cli/chat_mode/shell}/commands/conversation_restart.py +34 -30
- janito/cli/chat_mode/shell/commands/edit.py +25 -0
- janito/cli/chat_mode/shell/commands/help.py +16 -0
- janito/cli/chat_mode/shell/commands/history_view.py +93 -0
- janito/cli/chat_mode/shell/commands/lang.py +25 -0
- janito/cli/chat_mode/shell/commands/last.py +137 -0
- janito/cli/chat_mode/shell/commands/livelogs.py +49 -0
- janito/cli/chat_mode/shell/commands/multi.py +51 -0
- janito/cli/chat_mode/shell/commands/prompt.py +64 -0
- janito/cli/chat_mode/shell/commands/role.py +36 -0
- janito/cli/chat_mode/shell/commands/session.py +40 -0
- janito/{shell → cli/chat_mode/shell}/commands/session_control.py +2 -2
- janito/cli/chat_mode/shell/commands/termweb_log.py +92 -0
- janito/cli/chat_mode/shell/commands/tools.py +32 -0
- janito/{shell → cli/chat_mode/shell}/commands/utility.py +4 -7
- janito/{shell → cli/chat_mode/shell}/commands/verbose.py +5 -5
- janito/cli/chat_mode/shell/session/__init__.py +1 -0
- janito/{shell → cli/chat_mode/shell}/session/manager.py +9 -1
- janito/cli/chat_mode/toolbar.py +90 -0
- janito/cli/cli_commands/list_models.py +35 -0
- janito/cli/cli_commands/list_providers.py +9 -0
- janito/cli/cli_commands/list_tools.py +53 -0
- janito/cli/cli_commands/model_selection.py +50 -0
- janito/cli/cli_commands/model_utils.py +84 -0
- janito/cli/cli_commands/set_api_key.py +19 -0
- janito/cli/cli_commands/show_config.py +51 -0
- janito/cli/cli_commands/show_system_prompt.py +62 -0
- janito/cli/config.py +28 -0
- janito/cli/console.py +3 -0
- janito/cli/core/__init__.py +4 -0
- janito/cli/core/event_logger.py +59 -0
- janito/cli/core/getters.py +31 -0
- janito/cli/core/runner.py +141 -0
- janito/cli/core/setters.py +174 -0
- janito/cli/core/unsetters.py +54 -0
- janito/cli/main.py +8 -196
- janito/cli/main_cli.py +312 -0
- janito/cli/prompt_core.py +230 -0
- janito/cli/prompt_handler.py +6 -0
- janito/cli/rich_terminal_reporter.py +101 -0
- janito/cli/single_shot_mode/__init__.py +6 -0
- janito/cli/single_shot_mode/handler.py +137 -0
- janito/cli/termweb_starter.py +73 -24
- janito/cli/utils.py +25 -0
- janito/cli/verbose_output.py +196 -0
- janito/config.py +5 -0
- janito/config_manager.py +110 -0
- janito/conversation_history.py +30 -0
- janito/{agent/tools_utils/dir_walk_utils.py → dir_walk_utils.py} +3 -2
- janito/driver_events.py +98 -0
- janito/drivers/anthropic/driver.py +113 -0
- janito/drivers/azure_openai/driver.py +36 -0
- janito/drivers/driver_registry.py +33 -0
- janito/drivers/google_genai/driver.py +54 -0
- janito/drivers/google_genai/schema_generator.py +67 -0
- janito/drivers/mistralai/driver.py +41 -0
- janito/drivers/openai/driver.py +334 -0
- janito/event_bus/__init__.py +2 -0
- janito/event_bus/bus.py +68 -0
- janito/event_bus/event.py +15 -0
- janito/event_bus/handler.py +31 -0
- janito/event_bus/queue_bus.py +57 -0
- janito/exceptions.py +23 -0
- janito/formatting_token.py +54 -0
- janito/i18n/pt.py +1 -0
- janito/llm/__init__.py +5 -0
- janito/llm/agent.py +443 -0
- janito/llm/auth.py +62 -0
- janito/llm/driver.py +239 -0
- janito/llm/driver_config.py +34 -0
- janito/llm/driver_config_builder.py +34 -0
- janito/llm/driver_input.py +12 -0
- janito/llm/message_parts.py +60 -0
- janito/llm/model.py +38 -0
- janito/llm/provider.py +187 -0
- janito/perf_singleton.py +3 -0
- janito/performance_collector.py +167 -0
- janito/provider_config.py +98 -0
- janito/provider_registry.py +152 -0
- janito/providers/__init__.py +7 -0
- janito/providers/anthropic/model_info.py +22 -0
- janito/providers/anthropic/provider.py +65 -0
- janito/providers/azure_openai/model_info.py +15 -0
- janito/providers/azure_openai/provider.py +72 -0
- janito/providers/deepseek/__init__.py +1 -0
- janito/providers/deepseek/model_info.py +16 -0
- janito/providers/deepseek/provider.py +91 -0
- janito/providers/google/__init__.py +1 -0
- janito/providers/google/model_info.py +40 -0
- janito/providers/google/provider.py +69 -0
- janito/providers/mistralai/model_info.py +37 -0
- janito/providers/mistralai/provider.py +69 -0
- janito/providers/openai/__init__.py +1 -0
- janito/providers/openai/model_info.py +137 -0
- janito/providers/openai/provider.py +107 -0
- janito/providers/openai/schema_generator.py +63 -0
- janito/providers/provider_static_info.py +21 -0
- janito/providers/registry.py +26 -0
- janito/report_events.py +38 -0
- janito/termweb/app.py +1 -1
- janito/tools/__init__.py +16 -0
- janito/tools/adapters/__init__.py +1 -0
- janito/tools/adapters/local/__init__.py +54 -0
- janito/tools/adapters/local/adapter.py +92 -0
- janito/{agent/tools → tools/adapters/local}/ask_user.py +30 -13
- janito/tools/adapters/local/copy_file.py +84 -0
- janito/{agent/tools → tools/adapters/local}/create_directory.py +11 -10
- janito/tools/adapters/local/create_file.py +82 -0
- janito/tools/adapters/local/delete_text_in_file.py +136 -0
- janito/{agent/tools → tools/adapters/local}/fetch_url.py +18 -19
- janito/tools/adapters/local/find_files.py +140 -0
- janito/tools/adapters/local/get_file_outline/core.py +151 -0
- janito/{agent/tools → tools/adapters/local}/get_file_outline/python_outline.py +125 -0
- janito/tools/adapters/local/get_file_outline/python_outline_v2.py +156 -0
- janito/{agent/tools → tools/adapters/local}/get_file_outline/search_outline.py +12 -7
- janito/{agent/tools → tools/adapters/local}/move_file.py +13 -9
- janito/tools/adapters/local/open_html_in_browser.py +34 -0
- janito/{agent/tools → tools/adapters/local}/open_url.py +7 -5
- janito/tools/adapters/local/python_code_run.py +165 -0
- janito/tools/adapters/local/python_command_run.py +163 -0
- janito/tools/adapters/local/python_file_run.py +162 -0
- janito/{agent/tools → tools/adapters/local}/remove_directory.py +15 -9
- janito/{agent/tools → tools/adapters/local}/remove_file.py +17 -14
- janito/{agent/tools → tools/adapters/local}/replace_text_in_file.py +27 -22
- janito/tools/adapters/local/run_bash_command.py +176 -0
- janito/tools/adapters/local/run_powershell_command.py +219 -0
- janito/{agent/tools → tools/adapters/local}/search_text/core.py +32 -12
- janito/{agent/tools → tools/adapters/local}/search_text/match_lines.py +13 -4
- janito/{agent/tools → tools/adapters/local}/search_text/pattern_utils.py +12 -4
- janito/{agent/tools → tools/adapters/local}/search_text/traverse_directory.py +15 -2
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/core.py +12 -11
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/css_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/html_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/js_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/json_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/markdown_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/ps1_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/python_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/xml_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/yaml_validator.py +1 -1
- janito/{agent/tools/get_lines.py → tools/adapters/local/view_file.py} +45 -27
- janito/tools/inspect_registry.py +17 -0
- janito/tools/tool_base.py +105 -0
- janito/tools/tool_events.py +58 -0
- janito/tools/tool_run_exception.py +12 -0
- janito/{agent → tools}/tool_use_tracker.py +2 -4
- janito/{agent/tools_utils/utils.py → tools/tool_utils.py} +18 -9
- janito/tools/tools_adapter.py +207 -0
- janito/tools/tools_schema.py +104 -0
- janito/utils.py +11 -0
- janito/version.py +4 -0
- janito-2.0.1.dist-info/METADATA +232 -0
- janito-2.0.1.dist-info/RECORD +181 -0
- janito/agent/__init__.py +0 -0
- janito/agent/api_exceptions.py +0 -4
- janito/agent/config.py +0 -147
- janito/agent/config_defaults.py +0 -12
- janito/agent/config_utils.py +0 -0
- janito/agent/content_handler.py +0 -0
- janito/agent/conversation.py +0 -238
- janito/agent/conversation_api.py +0 -306
- janito/agent/conversation_exceptions.py +0 -18
- janito/agent/conversation_tool_calls.py +0 -39
- janito/agent/conversation_ui.py +0 -17
- janito/agent/event.py +0 -24
- janito/agent/event_dispatcher.py +0 -24
- janito/agent/event_handler_protocol.py +0 -5
- janito/agent/event_system.py +0 -15
- janito/agent/llm_conversation_history.py +0 -82
- janito/agent/message_handler.py +0 -20
- janito/agent/message_handler_protocol.py +0 -5
- janito/agent/openai_client.py +0 -149
- janito/agent/openai_schema_generator.py +0 -187
- janito/agent/profile_manager.py +0 -96
- janito/agent/queued_message_handler.py +0 -50
- janito/agent/rich_live.py +0 -32
- janito/agent/rich_message_handler.py +0 -115
- janito/agent/runtime_config.py +0 -36
- janito/agent/test_handler_protocols.py +0 -47
- janito/agent/test_openai_schema_generator.py +0 -93
- janito/agent/tests/__init__.py +0 -1
- janito/agent/tool_base.py +0 -63
- janito/agent/tool_executor.py +0 -122
- janito/agent/tool_registry.py +0 -49
- janito/agent/tools/__init__.py +0 -47
- janito/agent/tools/create_file.py +0 -59
- janito/agent/tools/delete_text_in_file.py +0 -97
- janito/agent/tools/find_files.py +0 -106
- janito/agent/tools/get_file_outline/core.py +0 -81
- janito/agent/tools/present_choices.py +0 -64
- janito/agent/tools/python_command_runner.py +0 -201
- janito/agent/tools/python_file_runner.py +0 -199
- janito/agent/tools/python_stdin_runner.py +0 -208
- janito/agent/tools/replace_file.py +0 -72
- janito/agent/tools/run_bash_command.py +0 -218
- janito/agent/tools/run_powershell_command.py +0 -251
- janito/agent/tools_utils/__init__.py +0 -1
- janito/agent/tools_utils/action_type.py +0 -7
- janito/agent/tools_utils/test_gitignore_utils.py +0 -46
- janito/cli/_livereload_log_utils.py +0 -13
- janito/cli/_print_config.py +0 -96
- janito/cli/_termweb_log_utils.py +0 -17
- janito/cli/_utils.py +0 -9
- janito/cli/arg_parser.py +0 -272
- janito/cli/cli_main.py +0 -281
- janito/cli/config_commands.py +0 -211
- janito/cli/config_runner.py +0 -35
- janito/cli/formatting_runner.py +0 -12
- janito/cli/livereload_starter.py +0 -60
- janito/cli/logging_setup.py +0 -38
- janito/cli/one_shot.py +0 -80
- janito/livereload/app.py +0 -25
- janito/rich_utils.py +0 -59
- janito/shell/__init__.py +0 -0
- janito/shell/commands/__init__.py +0 -61
- janito/shell/commands/config.py +0 -22
- janito/shell/commands/edit.py +0 -24
- janito/shell/commands/history_view.py +0 -18
- janito/shell/commands/lang.py +0 -19
- janito/shell/commands/livelogs.py +0 -42
- janito/shell/commands/prompt.py +0 -62
- janito/shell/commands/termweb_log.py +0 -94
- janito/shell/commands/tools.py +0 -26
- janito/shell/commands/track.py +0 -36
- janito/shell/main.py +0 -326
- janito/shell/prompt/load_prompt.py +0 -57
- janito/shell/prompt/session_setup.py +0 -57
- janito/shell/session/config.py +0 -109
- janito/shell/session/history.py +0 -0
- janito/shell/ui/interactive.py +0 -226
- janito/termweb/static/editor.css +0 -158
- janito/termweb/static/editor.css.bak +0 -145
- janito/termweb/static/editor.html +0 -46
- janito/termweb/static/editor.html.bak +0 -46
- janito/termweb/static/editor.js +0 -265
- janito/termweb/static/editor.js.bak +0 -259
- janito/termweb/static/explorer.html.bak +0 -59
- janito/termweb/static/favicon.ico +0 -0
- janito/termweb/static/favicon.ico.bak +0 -0
- janito/termweb/static/index.html +0 -53
- janito/termweb/static/index.html.bak +0 -54
- janito/termweb/static/index.html.bak.bak +0 -175
- janito/termweb/static/landing.html.bak +0 -36
- janito/termweb/static/termicon.svg +0 -1
- janito/termweb/static/termweb.css +0 -214
- janito/termweb/static/termweb.css.bak +0 -237
- janito/termweb/static/termweb.js +0 -162
- janito/termweb/static/termweb.js.bak +0 -168
- janito/termweb/static/termweb.js.bak.bak +0 -157
- janito/termweb/static/termweb_quickopen.js +0 -135
- janito/termweb/static/termweb_quickopen.js.bak +0 -125
- janito/tests/test_rich_utils.py +0 -44
- janito/web/__init__.py +0 -0
- janito/web/__main__.py +0 -25
- janito/web/app.py +0 -145
- janito-1.14.3.dist-info/METADATA +0 -313
- janito-1.14.3.dist-info/RECORD +0 -162
- janito-1.14.3.dist-info/licenses/LICENSE +0 -21
- /janito/{shell → cli/chat_mode/shell}/input_history.py +0 -0
- /janito/{shell/commands/session.py → cli/chat_mode/shell/session/history.py} +0 -0
- /janito/{agent/tools_utils/formatting.py → formatting.py} +0 -0
- /janito/{agent/tools_utils/gitignore_utils.py → gitignore_utils.py} +0 -0
- /janito/{agent/platform_discovery.py → platform_discovery.py} +0 -0
- /janito/{agent/tools → tools/adapters/local}/get_file_outline/__init__.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/get_file_outline/markdown_outline.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/search_text/__init__.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/validate_file_syntax/__init__.py +0 -0
- {janito-1.14.3.dist-info → janito-2.0.1.dist-info}/WHEEL +0 -0
- {janito-1.14.3.dist-info → janito-2.0.1.dist-info}/entry_points.txt +0 -0
- {janito-1.14.3.dist-info → janito-2.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
import http.client
|
2
|
+
from rich.console import Console
|
3
|
+
from janito.cli.config import config
|
4
|
+
from janito.cli.console import shared_console
|
5
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
6
|
+
|
7
|
+
|
8
|
+
class TermwebLogTailShellHandler(ShellCmdHandler):
|
9
|
+
help_text = "Show the last lines of the latest termweb logs"
|
10
|
+
|
11
|
+
def run(self):
|
12
|
+
lines = 20
|
13
|
+
args = self.after_cmd_line.strip().split()
|
14
|
+
if args and args[0].isdigit():
|
15
|
+
lines = int(args[0])
|
16
|
+
stdout_path = self.shell_state.termweb_stdout_path if self.shell_state else None
|
17
|
+
stderr_path = self.shell_state.termweb_stderr_path if self.shell_state else None
|
18
|
+
status = getattr(self.shell_state, "termweb_status", None)
|
19
|
+
live_status = getattr(self.shell_state, "termweb_live_status", None)
|
20
|
+
status_checked = getattr(self.shell_state, "termweb_live_checked_time", None)
|
21
|
+
shared_console.print(
|
22
|
+
f"[bold cyan][termweb] Current run status: {status} | Last health check: {live_status} at {status_checked}"
|
23
|
+
)
|
24
|
+
if not stdout_path and not stderr_path:
|
25
|
+
shared_console.print(
|
26
|
+
"[yellow][termweb] No termweb log files found for this session.[/yellow]"
|
27
|
+
)
|
28
|
+
return
|
29
|
+
stdout_lines = stderr_lines = None
|
30
|
+
if stdout_path:
|
31
|
+
try:
|
32
|
+
with open(stdout_path, encoding="utf-8") as f:
|
33
|
+
stdout_lines = f.readlines()[-lines:]
|
34
|
+
if stdout_lines:
|
35
|
+
shared_console.print(
|
36
|
+
f"[yellow][termweb][stdout] Tail of {stdout_path}:\n"
|
37
|
+
+ "".join(stdout_lines)
|
38
|
+
)
|
39
|
+
except Exception:
|
40
|
+
pass
|
41
|
+
if stderr_path:
|
42
|
+
try:
|
43
|
+
with open(stderr_path, encoding="utf-8") as f:
|
44
|
+
stderr_lines = f.readlines()[-lines:]
|
45
|
+
if stderr_lines:
|
46
|
+
shared_console.print(
|
47
|
+
f"[red][termweb][stderr] Tail of {stderr_path}:\n"
|
48
|
+
+ "".join(stderr_lines)
|
49
|
+
)
|
50
|
+
except Exception:
|
51
|
+
pass
|
52
|
+
if (not stdout_path or not stdout_lines) and (
|
53
|
+
not stderr_path or not stderr_lines
|
54
|
+
):
|
55
|
+
shared_console.print("[termweb] No output or errors captured in logs.")
|
56
|
+
|
57
|
+
|
58
|
+
def handle_termweb_status(*args, shell_state=None, **kwargs):
|
59
|
+
if shell_state is None:
|
60
|
+
console.print(
|
61
|
+
"[red]No shell state available. Cannot determine termweb status.[/red]"
|
62
|
+
)
|
63
|
+
return
|
64
|
+
from janito.cli.config import get_termweb_port
|
65
|
+
|
66
|
+
port = get_termweb_port()
|
67
|
+
port_source = "config"
|
68
|
+
pid = getattr(shell_state, "termweb_pid", None)
|
69
|
+
stdout_path = getattr(shell_state, "termweb_stdout_path", None)
|
70
|
+
stderr_path = getattr(shell_state, "termweb_stderr_path", None)
|
71
|
+
running = False
|
72
|
+
if port and hasattr(shell_state, "termweb_live_status"):
|
73
|
+
running = shell_state.termweb_live_status == "online"
|
74
|
+
console.print("[bold cyan]TermWeb Server Status:[/bold cyan]")
|
75
|
+
console.print(f" Running: {'[green]Yes[/green]' if running else '[red]No[/red]'}")
|
76
|
+
if pid:
|
77
|
+
console.print(f" PID: {pid}")
|
78
|
+
if port:
|
79
|
+
console.print(f" Port: {port} (from {port_source})")
|
80
|
+
url = f"http://localhost:{port}/"
|
81
|
+
console.print(f" URL: [underline blue]{url}[/underline blue]")
|
82
|
+
else:
|
83
|
+
console.print(" [yellow]No port configured in config.[/yellow]")
|
84
|
+
if stdout_path:
|
85
|
+
console.print(f" Stdout log: {stdout_path}")
|
86
|
+
if stderr_path:
|
87
|
+
console.print(f" Stderr log: {stderr_path}")
|
88
|
+
|
89
|
+
|
90
|
+
handle_termweb_status.help_text = (
|
91
|
+
"Show status information about the running termweb server"
|
92
|
+
)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
|
4
|
+
class ToolsShellHandler(ShellCmdHandler):
|
5
|
+
help_text = "List available tools"
|
6
|
+
|
7
|
+
def run(self):
|
8
|
+
try:
|
9
|
+
import janito.tools # Ensure all tools are registered
|
10
|
+
registry = janito.tools.get_local_tools_adapter()
|
11
|
+
tools = registry.list_tools()
|
12
|
+
shared_console.print("Registered tools:" if tools else "No tools registered.")
|
13
|
+
for tool in tools:
|
14
|
+
shared_console.print(f"- {tool}")
|
15
|
+
|
16
|
+
# Check for execution tools
|
17
|
+
# We assume shell_state.allow_execution is set if -x is used
|
18
|
+
allow_execution = False
|
19
|
+
if hasattr(self, 'shell_state') and self.shell_state is not None:
|
20
|
+
allow_execution = getattr(self.shell_state, 'allow_execution', False)
|
21
|
+
|
22
|
+
# Find all possible execution tools (by convention: provides_execution = True)
|
23
|
+
exec_tools = []
|
24
|
+
for tool_instance in registry.get_tools():
|
25
|
+
if getattr(tool_instance, 'provides_execution', False):
|
26
|
+
exec_tools.append(tool_instance.tool_name)
|
27
|
+
|
28
|
+
if not allow_execution and exec_tools:
|
29
|
+
shared_console.print("[yellow]⚠️ Warning: Execution tools (e.g., commands, code execution) are disabled. Use -x to enable them.[/yellow]")
|
30
|
+
|
31
|
+
except Exception as e:
|
32
|
+
shared_console.print(f"[red]Error loading tools: {e}[/red]")
|
@@ -1,17 +1,14 @@
|
|
1
|
-
def handle_help(
|
2
|
-
from janito.shell.commands import COMMAND_HANDLERS
|
1
|
+
def handle_help(**kwargs):
|
2
|
+
from janito.cli.chat_mode.shell.commands import COMMAND_HANDLERS
|
3
3
|
|
4
4
|
console.print("[bold green]Available commands:[/bold green]")
|
5
5
|
for cmd, handler in COMMAND_HANDLERS.items():
|
6
6
|
help_text = getattr(handler, "help_text", None)
|
7
7
|
if help_text:
|
8
8
|
console.print(f" {cmd} - {help_text}")
|
9
|
-
console.print(
|
10
|
-
"[bold cyan]!command[/]: Run a shell/cmd command without exiting the shell (e.g., !dir or !ls)"
|
11
|
-
)
|
12
9
|
|
13
10
|
|
14
|
-
def handle_clear(
|
11
|
+
def handle_clear(**kwargs):
|
15
12
|
import os
|
16
13
|
|
17
14
|
os.system("cls" if os.name == "nt" else "clear")
|
@@ -20,7 +17,7 @@ def handle_clear(console, **kwargs):
|
|
20
17
|
handle_clear.help_text = "Clear the terminal screen"
|
21
18
|
|
22
19
|
|
23
|
-
def handle_multi(
|
20
|
+
def handle_multi(shell_state=None, **kwargs):
|
24
21
|
console.print(
|
25
22
|
"[bold yellow]Multiline mode activated. Provide or write your text and press Esc + Enter to submit.[/bold yellow]"
|
26
23
|
)
|
@@ -1,9 +1,9 @@
|
|
1
|
-
from janito.
|
1
|
+
from janito.cli.config import config
|
2
2
|
|
3
3
|
|
4
|
-
def handle_verbose(
|
4
|
+
def handle_verbose(shell_state=None, **kwargs):
|
5
5
|
args = kwargs.get("args", [])
|
6
|
-
verbose =
|
6
|
+
verbose = config.get("verbose") or False
|
7
7
|
if not args:
|
8
8
|
status = "ON" if verbose else "OFF"
|
9
9
|
console.print(
|
@@ -12,12 +12,12 @@ def handle_verbose(console, shell_state=None, **kwargs):
|
|
12
12
|
return
|
13
13
|
arg = args[0].lower()
|
14
14
|
if arg == "on":
|
15
|
-
|
15
|
+
config.runtime_set("verbose", True)
|
16
16
|
console.print(
|
17
17
|
"[bold green]/verbose:[/bold green] Verbose mode is now [bold]ON[/bold]."
|
18
18
|
)
|
19
19
|
elif arg == "off":
|
20
|
-
|
20
|
+
config.runtime_set("verbose", False)
|
21
21
|
console.print(
|
22
22
|
"[bold green]/verbose:[/bold green] Verbose mode is now [bold]OFF[/bold]."
|
23
23
|
)
|
@@ -0,0 +1 @@
|
|
1
|
+
from .history import handle_history
|
@@ -32,6 +32,14 @@ def get_session_id():
|
|
32
32
|
return _current_session_id
|
33
33
|
|
34
34
|
|
35
|
+
def set_role(role):
|
36
|
+
"""Set the current role."""
|
37
|
+
# No longer needed: from janito.cli.runtime_config import RuntimeConfig
|
38
|
+
rc = RuntimeConfig()
|
39
|
+
rc.role = role
|
40
|
+
rc.save()
|
41
|
+
|
42
|
+
|
35
43
|
def load_last_summary(path=".janito/last_conversation.json"):
|
36
44
|
if not os.path.exists(path):
|
37
45
|
return None
|
@@ -81,7 +89,7 @@ def save_conversation(messages, prompts, usage_info=None, path=None):
|
|
81
89
|
def usage_serializer(obj):
|
82
90
|
if hasattr(obj, "to_dict"):
|
83
91
|
return obj.to_dict()
|
84
|
-
if hasattr(obj, "
|
92
|
+
if hasattr(obj, "__dict"):
|
85
93
|
return obj.__dict__
|
86
94
|
return str(obj)
|
87
95
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
from prompt_toolkit.formatted_text import HTML
|
2
|
+
from janito.performance_collector import PerformanceCollector
|
3
|
+
from janito.cli.config import config
|
4
|
+
from janito.version import __version__ as VERSION
|
5
|
+
|
6
|
+
|
7
|
+
def format_tokens(n, tag=None):
|
8
|
+
if n is None:
|
9
|
+
return "?"
|
10
|
+
if n < 1000:
|
11
|
+
val = str(n)
|
12
|
+
elif n < 1000000:
|
13
|
+
val = f"{n/1000:.1f}k"
|
14
|
+
else:
|
15
|
+
val = f"{n/1000000:.1f}M"
|
16
|
+
return f"<{tag}>{val}</{tag}>" if tag else val
|
17
|
+
|
18
|
+
|
19
|
+
def assemble_first_line(provider_name, model_name, role, agent=None):
|
20
|
+
return f" Janito {VERSION} | Provider: <provider>{provider_name}</provider> | Model: <model>{model_name}</model> | Role: <role>{role}</role>"
|
21
|
+
|
22
|
+
|
23
|
+
def assemble_bindings_line(width):
|
24
|
+
return (
|
25
|
+
f" <key-label>F1</key-label>: Restart conversation | "
|
26
|
+
f"<b>/help</b>: Help | "
|
27
|
+
f"<key-label>F12</key-label>: Do It "
|
28
|
+
)
|
29
|
+
|
30
|
+
|
31
|
+
def get_toolbar_func(perf: PerformanceCollector, msg_count: int, shell_state):
|
32
|
+
from prompt_toolkit.application.current import get_app
|
33
|
+
import importlib
|
34
|
+
|
35
|
+
def get_toolbar():
|
36
|
+
width = get_app().output.get_size().columns
|
37
|
+
provider_name = "?"
|
38
|
+
model_name = "?"
|
39
|
+
role = "?"
|
40
|
+
agent = shell_state.agent if hasattr(shell_state, "agent") else None
|
41
|
+
termweb_support = getattr(shell_state, "termweb_support", False)
|
42
|
+
termweb_port = (
|
43
|
+
shell_state.termweb_port if hasattr(shell_state, "termweb_port") else None
|
44
|
+
)
|
45
|
+
termweb_status = (
|
46
|
+
shell_state.termweb_status
|
47
|
+
if hasattr(shell_state, "termweb_status")
|
48
|
+
else None
|
49
|
+
)
|
50
|
+
# Use cached liveness check only (set by background thread in shell_state)
|
51
|
+
this_termweb_status = termweb_status
|
52
|
+
if not termweb_support:
|
53
|
+
this_termweb_status = None
|
54
|
+
elif termweb_status == "starting" or termweb_status is None:
|
55
|
+
this_termweb_status = termweb_status
|
56
|
+
else:
|
57
|
+
live_status = (
|
58
|
+
shell_state.termweb_live_status
|
59
|
+
if hasattr(shell_state, "termweb_live_status")
|
60
|
+
else None
|
61
|
+
)
|
62
|
+
if live_status is not None:
|
63
|
+
this_termweb_status = live_status
|
64
|
+
if agent is not None:
|
65
|
+
# Use agent API to get provider and model name
|
66
|
+
provider_name = (
|
67
|
+
agent.get_provider_name()
|
68
|
+
if hasattr(agent, "get_provider_name")
|
69
|
+
else "?"
|
70
|
+
)
|
71
|
+
model_name = (
|
72
|
+
agent.get_model_name() if hasattr(agent, "get_model_name") else "?"
|
73
|
+
)
|
74
|
+
if hasattr(agent, "template_vars"):
|
75
|
+
role = agent.template_vars.get("role", "?")
|
76
|
+
usage = perf.get_last_request_usage()
|
77
|
+
first_line = assemble_first_line(provider_name, model_name, role, agent=agent)
|
78
|
+
|
79
|
+
bindings_line = assemble_bindings_line(width)
|
80
|
+
toolbar_text = first_line + "\n" + bindings_line
|
81
|
+
# Add termweb status if available, after the F12 line
|
82
|
+
if this_termweb_status == "online" and termweb_port:
|
83
|
+
toolbar_text += f"\n<termweb> Termweb </termweb>Online<termweb> at <u>http://localhost:{termweb_port}</u></termweb>"
|
84
|
+
elif this_termweb_status == "starting":
|
85
|
+
toolbar_text += "\n<termweb> Termweb </termweb>Starting"
|
86
|
+
elif this_termweb_status == "offline":
|
87
|
+
toolbar_text += "\n<termweb> Termweb </termweb>Offline"
|
88
|
+
return HTML(toolbar_text)
|
89
|
+
|
90
|
+
return get_toolbar
|
@@ -0,0 +1,35 @@
|
|
1
|
+
"""
|
2
|
+
CLI Command: List models for the specified/current provider
|
3
|
+
"""
|
4
|
+
|
5
|
+
from janito.cli.cli_commands.model_utils import _print_models_table
|
6
|
+
import sys
|
7
|
+
|
8
|
+
_provider_instance = None
|
9
|
+
|
10
|
+
|
11
|
+
def get_provider_instance():
|
12
|
+
global _provider_instance
|
13
|
+
if _provider_instance is None:
|
14
|
+
_provider_instance = setup_provider()
|
15
|
+
return _provider_instance
|
16
|
+
|
17
|
+
|
18
|
+
def handle_list_models(args, provider_instance):
|
19
|
+
provider_name = getattr(provider_instance, "name", None)
|
20
|
+
if not provider_name:
|
21
|
+
print(
|
22
|
+
"Error: Provider must be specified with --provider or set as default before listing models."
|
23
|
+
)
|
24
|
+
sys.exit(1)
|
25
|
+
try:
|
26
|
+
models = list(provider_instance.get_model_info().values())
|
27
|
+
if models and isinstance(models[0], dict):
|
28
|
+
_print_models_table(models, provider_name)
|
29
|
+
else:
|
30
|
+
print(f"Supported models for provider '{provider_name}':")
|
31
|
+
for m in models:
|
32
|
+
print(f"- {m}")
|
33
|
+
except Exception as e:
|
34
|
+
print(f"Error listing models for provider '{provider_name}': {e}")
|
35
|
+
sys.exit(0)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
"""
|
2
|
+
CLI Command: List available tools
|
3
|
+
"""
|
4
|
+
|
5
|
+
|
6
|
+
def handle_list_tools(args=None):
|
7
|
+
from janito.tools.adapters.local.adapter import LocalToolsAdapter
|
8
|
+
import janito.tools # Ensure all tools are registered
|
9
|
+
|
10
|
+
registry = janito.tools.get_local_tools_adapter()
|
11
|
+
tools = registry.list_tools()
|
12
|
+
if tools:
|
13
|
+
from rich.table import Table
|
14
|
+
from rich.console import Console
|
15
|
+
console = Console()
|
16
|
+
# Get tool instances to check provides_execution and get info
|
17
|
+
tool_instances = {t.tool_name: t for t in registry.get_tools()}
|
18
|
+
normal_tools = []
|
19
|
+
exec_tools = []
|
20
|
+
for tool in tools:
|
21
|
+
inst = tool_instances.get(tool, None)
|
22
|
+
# Extract parameter names from run signature
|
23
|
+
param_names = []
|
24
|
+
if inst and hasattr(inst, "run"):
|
25
|
+
import inspect
|
26
|
+
sig = inspect.signature(inst.run)
|
27
|
+
param_names = [p for p in sig.parameters if p != "self"]
|
28
|
+
info = {
|
29
|
+
"name": tool,
|
30
|
+
"params": ", ".join(param_names),
|
31
|
+
}
|
32
|
+
if getattr(inst, "provides_execution", False):
|
33
|
+
exec_tools.append(info)
|
34
|
+
else:
|
35
|
+
normal_tools.append(info)
|
36
|
+
table = Table(title="Registered tools", show_header=True, header_style="bold", show_lines=False, box=None)
|
37
|
+
table.add_column("Name", style="cyan", no_wrap=True)
|
38
|
+
table.add_column("Parameters", style="yellow")
|
39
|
+
for info in normal_tools:
|
40
|
+
table.add_row(info["name"], info["params"] or "-")
|
41
|
+
console.print(table)
|
42
|
+
if exec_tools:
|
43
|
+
exec_table = Table(title="Execution tools (only available with -x)", show_header=True, header_style="bold", show_lines=False, box=None)
|
44
|
+
exec_table.add_column("Name", style="cyan", no_wrap=True)
|
45
|
+
exec_table.add_column("Parameters", style="yellow")
|
46
|
+
for info in exec_tools:
|
47
|
+
exec_table.add_row(info["name"], info["params"] or "-")
|
48
|
+
console.print(exec_table)
|
49
|
+
else:
|
50
|
+
print("No tools registered.")
|
51
|
+
import sys
|
52
|
+
|
53
|
+
sys.exit(0)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
"""
|
2
|
+
CLI Command: Validate and set the model provider selection
|
3
|
+
"""
|
4
|
+
|
5
|
+
from janito.cli.config import config
|
6
|
+
|
7
|
+
_provider_instance = None
|
8
|
+
|
9
|
+
|
10
|
+
def get_provider_instance():
|
11
|
+
global _provider_instance
|
12
|
+
if _provider_instance is None:
|
13
|
+
_provider_instance = setup_provider()
|
14
|
+
return _provider_instance
|
15
|
+
|
16
|
+
|
17
|
+
def handle_model_selection(args):
|
18
|
+
if getattr(args, "model", None):
|
19
|
+
provider_instance = get_provider_instance()
|
20
|
+
provider_name = getattr(provider_instance, "name", None)
|
21
|
+
if not provider_name:
|
22
|
+
print(
|
23
|
+
"Error: Provider must be specified with --provider or set as default before selecting a model."
|
24
|
+
)
|
25
|
+
import sys
|
26
|
+
|
27
|
+
sys.exit(1)
|
28
|
+
if not validate_model_for_provider(provider_name, args.model):
|
29
|
+
sys.exit(1)
|
30
|
+
config.runtime_set("model", args.model)
|
31
|
+
|
32
|
+
|
33
|
+
def validate_model_for_provider(provider_name, model_name):
|
34
|
+
try:
|
35
|
+
provider_instance = get_provider_instance()
|
36
|
+
info_dict = provider_instance.get_model_info()
|
37
|
+
available_names = [
|
38
|
+
m["name"] for m in info_dict.values() if isinstance(m, dict) and "name" in m
|
39
|
+
]
|
40
|
+
if model_name in available_names:
|
41
|
+
return True
|
42
|
+
else:
|
43
|
+
print(
|
44
|
+
f"Error: Model '{model_name}' is not available for provider '{provider_name}'."
|
45
|
+
)
|
46
|
+
print(f"Available models: {', '.join(available_names)}")
|
47
|
+
return False
|
48
|
+
except Exception as e:
|
49
|
+
print(f"Error validating model for provider '{provider_name}': {e}")
|
50
|
+
return False
|
@@ -0,0 +1,84 @@
|
|
1
|
+
"""
|
2
|
+
Utilities for model-related CLI output
|
3
|
+
"""
|
4
|
+
|
5
|
+
|
6
|
+
def _print_models_table(models, provider_name):
|
7
|
+
from rich.table import Table
|
8
|
+
from rich.console import Console
|
9
|
+
|
10
|
+
headers = [
|
11
|
+
"name",
|
12
|
+
"open",
|
13
|
+
"context",
|
14
|
+
"max_input",
|
15
|
+
"max_cot",
|
16
|
+
"max_response",
|
17
|
+
"thinking_supported",
|
18
|
+
"driver",
|
19
|
+
]
|
20
|
+
display_headers = [
|
21
|
+
"Model Name",
|
22
|
+
"Vendor",
|
23
|
+
"context",
|
24
|
+
"max_input",
|
25
|
+
"max_cot",
|
26
|
+
"max_response",
|
27
|
+
"Thinking",
|
28
|
+
"Driver",
|
29
|
+
]
|
30
|
+
table = Table(title=f"Supported models for provider '{provider_name}'")
|
31
|
+
_add_table_columns(table, display_headers)
|
32
|
+
num_fields = {"context", "max_input", "max_cot", "max_response"}
|
33
|
+
for m in models:
|
34
|
+
row = [str(m.get("name", ""))]
|
35
|
+
row.extend(_build_model_row(m, headers, num_fields))
|
36
|
+
table.add_row(*row)
|
37
|
+
console = Console()
|
38
|
+
console.print(table)
|
39
|
+
|
40
|
+
|
41
|
+
def _add_table_columns(table, display_headers):
|
42
|
+
for i, h in enumerate(display_headers):
|
43
|
+
justify = "right" if i == 0 else "center"
|
44
|
+
table.add_column(h, style="bold", justify=justify)
|
45
|
+
|
46
|
+
|
47
|
+
def _format_k(val):
|
48
|
+
try:
|
49
|
+
n = int(val)
|
50
|
+
if n >= 1000:
|
51
|
+
return f"{n // 1000}k"
|
52
|
+
return str(n)
|
53
|
+
except Exception:
|
54
|
+
return str(val)
|
55
|
+
|
56
|
+
|
57
|
+
def _build_model_row(m, headers, num_fields):
|
58
|
+
def format_driver(val):
|
59
|
+
if isinstance(val, (list, tuple)):
|
60
|
+
return ", ".join(val)
|
61
|
+
val_str = str(val)
|
62
|
+
return val_str.removesuffix("ModelDriver").strip()
|
63
|
+
|
64
|
+
row = []
|
65
|
+
for h in headers[1:]:
|
66
|
+
v = m.get(h, "")
|
67
|
+
if h in num_fields and v not in ("", "N/A"):
|
68
|
+
if (
|
69
|
+
h in ("context", "max_input")
|
70
|
+
and isinstance(v, (list, tuple))
|
71
|
+
and len(v) == 2
|
72
|
+
):
|
73
|
+
row.append(f"{_format_k(v[0])} / {_format_k(v[1])}")
|
74
|
+
else:
|
75
|
+
row.append(_format_k(v))
|
76
|
+
elif h == "open":
|
77
|
+
row.append("Open" if v is True or v == "Open" else "Locked")
|
78
|
+
elif h == "thinking_supported":
|
79
|
+
row.append("📖" if v is True or v == "True" else "")
|
80
|
+
elif h == "driver":
|
81
|
+
row.append(format_driver(v))
|
82
|
+
else:
|
83
|
+
row.append(str(v))
|
84
|
+
return row
|
@@ -0,0 +1,19 @@
|
|
1
|
+
"""
|
2
|
+
CLI Command: Set API key for the current or selected provider
|
3
|
+
"""
|
4
|
+
|
5
|
+
from janito.provider_config import set_api_key
|
6
|
+
from janito.llm.auth import LLMAuthManager
|
7
|
+
|
8
|
+
|
9
|
+
def handle_set_api_key(args):
|
10
|
+
api_key = getattr(args, "set_api_key", None)
|
11
|
+
provider = getattr(args, "provider", None)
|
12
|
+
if not provider:
|
13
|
+
print("Error: --set-api-key requires -p/--provider to be specified.")
|
14
|
+
return
|
15
|
+
set_api_key(provider, api_key)
|
16
|
+
auth_manager = LLMAuthManager()
|
17
|
+
print(
|
18
|
+
f"API key set for provider '{provider}'. Auth file updated: {auth_manager._auth_file}"
|
19
|
+
)
|
@@ -0,0 +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
|
+
)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
"""
|
2
|
+
CLI Command: Show the resolved system prompt for the main agent (single-shot mode)
|
3
|
+
"""
|
4
|
+
|
5
|
+
from janito.cli.core.runner import prepare_llm_driver_config
|
6
|
+
from janito.platform_discovery import PlatformDiscovery
|
7
|
+
from pathlib import Path
|
8
|
+
from jinja2 import Template
|
9
|
+
import importlib.resources
|
10
|
+
|
11
|
+
|
12
|
+
def handle_show_system_prompt(args):
|
13
|
+
# Collect modifiers as in JanitoCLI
|
14
|
+
from janito.cli.main_cli import MODIFIER_KEYS
|
15
|
+
|
16
|
+
modifiers = {
|
17
|
+
k: getattr(args, k) for k in MODIFIER_KEYS if getattr(args, k, None) is not None
|
18
|
+
}
|
19
|
+
provider, llm_driver_config, agent_role = prepare_llm_driver_config(args, modifiers)
|
20
|
+
if provider is None or llm_driver_config is None:
|
21
|
+
print("Error: Could not resolve provider or LLM driver config.")
|
22
|
+
return
|
23
|
+
|
24
|
+
# Prepare context for Jinja2 rendering
|
25
|
+
context = {}
|
26
|
+
context["role"] = agent_role or "software developer"
|
27
|
+
pd = PlatformDiscovery()
|
28
|
+
context["platform"] = pd.get_platform_name()
|
29
|
+
context["python_version"] = pd.get_python_version()
|
30
|
+
context["shell_info"] = pd.detect_shell()
|
31
|
+
|
32
|
+
# Locate and load the system prompt template
|
33
|
+
templates_dir = (
|
34
|
+
Path(__file__).parent.parent.parent / "agent" / "templates" / "profiles"
|
35
|
+
)
|
36
|
+
template_path = templates_dir / "system_prompt_template_main.txt.j2"
|
37
|
+
template_content = None
|
38
|
+
if template_path.exists():
|
39
|
+
with open(template_path, "r", encoding="utf-8") as file:
|
40
|
+
template_content = file.read()
|
41
|
+
else:
|
42
|
+
# Try package import fallback
|
43
|
+
try:
|
44
|
+
with importlib.resources.files("janito.agent.templates.profiles").joinpath(
|
45
|
+
"system_prompt_template_main.txt.j2"
|
46
|
+
).open("r", encoding="utf-8") as file:
|
47
|
+
template_content = file.read()
|
48
|
+
except (FileNotFoundError, ModuleNotFoundError, AttributeError):
|
49
|
+
print(
|
50
|
+
f"[janito] Could not find system_prompt_template_main.txt.j2 in {template_path} nor in janito.agent.templates.profiles package."
|
51
|
+
)
|
52
|
+
print("No system prompt is set or resolved for this configuration.")
|
53
|
+
return
|
54
|
+
|
55
|
+
template = Template(template_content)
|
56
|
+
system_prompt = template.render(**context)
|
57
|
+
|
58
|
+
print("\n--- System Prompt (resolved) ---\n")
|
59
|
+
print(system_prompt)
|
60
|
+
print("\n-------------------------------\n")
|
61
|
+
if agent_role:
|
62
|
+
print(f"[Role: {agent_role}]")
|