janito 1.14.2__py3-none-any.whl → 2.0.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 -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/{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.0.dist-info/METADATA +232 -0
- janito-2.0.0.dist-info/RECORD +180 -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.2.dist-info/METADATA +0 -306
- janito-1.14.2.dist-info/RECORD +0 -162
- janito-1.14.2.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.2.dist-info → janito-2.0.0.dist-info}/WHEEL +0 -0
- {janito-1.14.2.dist-info → janito-2.0.0.dist-info}/entry_points.txt +0 -0
- {janito-1.14.2.dist-info → janito-2.0.0.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,14 @@
|
|
1
1
|
import os
|
2
|
+
from janito.cli.chat_mode.shell.session.manager import reset_session_id
|
3
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
4
|
+
from janito.cli.console import shared_console
|
2
5
|
|
3
|
-
from janito.shell.session.manager import reset_session_id
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
def handle_restart(shell_state=None):
|
8
|
+
from janito.cli.chat_mode.shell.session.manager import (
|
9
|
+
load_last_conversation,
|
10
|
+
save_conversation,
|
11
|
+
)
|
8
12
|
|
9
13
|
reset_session_id()
|
10
14
|
save_path = os.path.join(".janito", "last_conversation.json")
|
@@ -23,52 +27,52 @@ def handle_restart(console, shell_state=None, **kwargs):
|
|
23
27
|
# Save to permanent chat history (let save_conversation pick session file)
|
24
28
|
save_conversation(messages, prompts, usage)
|
25
29
|
except Exception as e:
|
26
|
-
|
30
|
+
shared_console.print(
|
27
31
|
f"[bold red]Failed to update previous conversation history:[/bold red] {e}"
|
28
32
|
)
|
29
33
|
|
30
34
|
# Clear the terminal screen
|
31
|
-
|
35
|
+
shared_console.clear()
|
32
36
|
|
33
|
-
# Reset conversation history using
|
34
|
-
shell_state.
|
37
|
+
# Reset conversation history using the agent's method
|
38
|
+
if hasattr(shell_state, "agent") and shell_state.agent:
|
39
|
+
shell_state.agent.reset_conversation_history()
|
35
40
|
|
36
41
|
# Reset tool use tracker
|
37
42
|
try:
|
38
|
-
from janito.
|
43
|
+
from janito.tools.tool_use_tracker import ToolUseTracker
|
39
44
|
|
40
45
|
ToolUseTracker.instance().clear_history()
|
41
46
|
except Exception as e:
|
42
|
-
|
47
|
+
shared_console.print(
|
43
48
|
f"[bold yellow]Warning: Failed to reset tool use tracker:[/bold yellow] {e}"
|
44
49
|
)
|
45
|
-
# Set system prompt from agent template if available
|
46
|
-
if (
|
47
|
-
hasattr(shell_state, "profile_manager")
|
48
|
-
and shell_state.profile_manager
|
49
|
-
and hasattr(shell_state.profile_manager, "agent")
|
50
|
-
and shell_state.profile_manager.agent
|
51
|
-
and getattr(shell_state.profile_manager.agent, "system_prompt_template", None)
|
52
|
-
and not any(
|
53
|
-
m.get("role") == "system"
|
54
|
-
for m in shell_state.conversation_history.get_messages()
|
55
|
-
)
|
56
|
-
):
|
57
|
-
shell_state.conversation_history.set_system_message(
|
58
|
-
shell_state.profile_manager.agent.system_prompt_template
|
59
|
-
)
|
60
50
|
|
61
51
|
# Reset token usage info in-place so all references (including status bar) are updated
|
62
52
|
for k in ("prompt_tokens", "completion_tokens", "total_tokens"):
|
63
|
-
|
64
|
-
shell_state.last_usage_info[k] = 0
|
65
|
-
else:
|
66
|
-
shell_state.last_usage_info[k] = 0
|
53
|
+
shell_state.last_usage_info[k] = 0
|
67
54
|
shell_state.last_elapsed = None
|
68
55
|
|
69
|
-
|
56
|
+
# Reset the performance collector's last usage (so toolbar immediately reflects cleared stats)
|
57
|
+
try:
|
58
|
+
from janito.perf_singleton import performance_collector
|
59
|
+
|
60
|
+
performance_collector.reset_last_request_usage()
|
61
|
+
except Exception as e:
|
62
|
+
shared_console.print(
|
63
|
+
f"[bold yellow]Warning: Failed to reset PerformanceCollector token info:[/bold yellow] {e}"
|
64
|
+
)
|
65
|
+
|
66
|
+
shared_console.print(
|
70
67
|
"[bold green]Conversation history has been started (context reset).[/bold green]"
|
71
68
|
)
|
72
69
|
|
73
70
|
|
74
71
|
handle_restart.help_text = "Start a new conversation (reset context)"
|
72
|
+
|
73
|
+
|
74
|
+
class RestartShellHandler(ShellCmdHandler):
|
75
|
+
help_text = "Start a new conversation (reset context)"
|
76
|
+
|
77
|
+
def run(self):
|
78
|
+
handle_restart(self.shell_state)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import os
|
2
|
+
import webbrowser
|
3
|
+
from janito.cli.console import shared_console
|
4
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
5
|
+
|
6
|
+
|
7
|
+
class EditShellHandler(ShellCmdHandler):
|
8
|
+
help_text = "Open a file in the browser-based editor"
|
9
|
+
|
10
|
+
def run(self):
|
11
|
+
filename = self.after_cmd_line.strip()
|
12
|
+
if not filename:
|
13
|
+
shared_console.print("[red]Usage: /edit <filename>[/red]")
|
14
|
+
return
|
15
|
+
if not os.path.isfile(filename):
|
16
|
+
shared_console.print(f"[red]File not found:[/red] {filename}")
|
17
|
+
return
|
18
|
+
from janito.cli.config import get_termweb_port
|
19
|
+
|
20
|
+
port = get_termweb_port()
|
21
|
+
url = f"http://localhost:{port}/?path={filename}"
|
22
|
+
shared_console.print(
|
23
|
+
f"[green]Opening in browser:[/green] [underline blue]{url}[/underline blue]"
|
24
|
+
)
|
25
|
+
webbrowser.open(url)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
2
|
+
from janito.cli.console import shared_console
|
3
|
+
|
4
|
+
|
5
|
+
class HelpShellHandler(ShellCmdHandler):
|
6
|
+
help_text = "Show this help message"
|
7
|
+
|
8
|
+
def run(self):
|
9
|
+
from . import (
|
10
|
+
COMMAND_HANDLERS,
|
11
|
+
) # Import moved inside method to avoid circular import
|
12
|
+
|
13
|
+
shared_console.print("[bold magenta]Available commands:[/bold magenta]")
|
14
|
+
for cmd, handler_cls in sorted(COMMAND_HANDLERS.items()):
|
15
|
+
help_text = getattr(handler_cls, "help_text", "")
|
16
|
+
shared_console.print(f"[cyan]{cmd}[/cyan]: {help_text}")
|
@@ -0,0 +1,93 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
import json
|
4
|
+
|
5
|
+
TRIM_LENGTH = 200 # Max chars to show for args or outputs before trimming
|
6
|
+
|
7
|
+
|
8
|
+
def trim_value(val, trim_length=TRIM_LENGTH):
|
9
|
+
s = (
|
10
|
+
json.dumps(val, ensure_ascii=False)
|
11
|
+
if isinstance(val, (dict, list))
|
12
|
+
else str(val)
|
13
|
+
)
|
14
|
+
if len(s) > trim_length:
|
15
|
+
return s[:trim_length] + "... [trimmed]"
|
16
|
+
return s
|
17
|
+
|
18
|
+
|
19
|
+
class ViewShellHandler(ShellCmdHandler):
|
20
|
+
help_text = "Print the current LLM conversation history"
|
21
|
+
|
22
|
+
def run(self):
|
23
|
+
if not hasattr(self.shell_state, "agent") or self.shell_state.agent is None:
|
24
|
+
shared_console.print("[red]No agent found in shell state.[/red]")
|
25
|
+
return
|
26
|
+
conversation_history = self.shell_state.agent.conversation_history
|
27
|
+
messages = conversation_history.get_history()
|
28
|
+
if not messages:
|
29
|
+
shared_console.print("[yellow]Conversation history is empty.[/yellow]")
|
30
|
+
return
|
31
|
+
for i, msg in enumerate(messages, 1):
|
32
|
+
self._print_message(i, msg)
|
33
|
+
|
34
|
+
def _print_message(self, i, msg):
|
35
|
+
role = msg.get("role", "?")
|
36
|
+
content = msg.get("content", "")
|
37
|
+
metadata = msg.get("metadata")
|
38
|
+
is_tool_result = (
|
39
|
+
role == "function"
|
40
|
+
and isinstance(metadata, dict)
|
41
|
+
and metadata.get("is_tool_result")
|
42
|
+
)
|
43
|
+
is_tool_call = (
|
44
|
+
role == "tool_call"
|
45
|
+
or (
|
46
|
+
isinstance(metadata, dict)
|
47
|
+
and (
|
48
|
+
metadata.get("type") == "tool_call" or metadata.get("is_tool_call")
|
49
|
+
)
|
50
|
+
)
|
51
|
+
) and not is_tool_result
|
52
|
+
if is_tool_call:
|
53
|
+
self._print_tool_call(i, metadata, content)
|
54
|
+
elif is_tool_result:
|
55
|
+
self._print_tool_result(i, content)
|
56
|
+
else:
|
57
|
+
self._print_regular_message(i, role, content, metadata)
|
58
|
+
|
59
|
+
def _print_tool_call(self, i, metadata, content):
|
60
|
+
func_name = None
|
61
|
+
args = None
|
62
|
+
if isinstance(metadata, dict):
|
63
|
+
tool_call = metadata.get("tool_call")
|
64
|
+
if tool_call and isinstance(tool_call, dict):
|
65
|
+
func_name = (
|
66
|
+
tool_call.get("function") or tool_call.get("name") or "<unknown>"
|
67
|
+
)
|
68
|
+
args = tool_call.get("arguments") or tool_call.get("args") or {}
|
69
|
+
else:
|
70
|
+
func_name = metadata.get("name") or "<unknown>"
|
71
|
+
args = metadata.get("arguments") or metadata.get("args") or content
|
72
|
+
else:
|
73
|
+
func_name = "<unknown>"
|
74
|
+
args = content
|
75
|
+
trimmed_args = trim_value(args)
|
76
|
+
shared_console.print(
|
77
|
+
f"[bold]{i}. TOOL_CALL:[/bold] {func_name}({trimmed_args})"
|
78
|
+
)
|
79
|
+
|
80
|
+
def _print_tool_result(self, i, content):
|
81
|
+
trimmed_output = trim_value(content)
|
82
|
+
if "\n" in trimmed_output:
|
83
|
+
shared_console.print(f"[bold]{i}. TOOL_RESULT:[/bold]")
|
84
|
+
for line in trimmed_output.splitlines():
|
85
|
+
shared_console.print(line)
|
86
|
+
else:
|
87
|
+
shared_console.print(f"[bold]{i}. TOOL_RESULT:[/bold] {trimmed_output}")
|
88
|
+
|
89
|
+
def _print_regular_message(self, i, role, content, metadata):
|
90
|
+
trimmed_content = trim_value(content)
|
91
|
+
shared_console.print(f"[bold]{i}. {role}:[/bold] {trimmed_content}")
|
92
|
+
if metadata:
|
93
|
+
shared_console.print(f" [cyan]metadata:[/cyan] {metadata}")
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from janito.cli.config import config
|
2
|
+
import janito.i18n as i18n
|
3
|
+
|
4
|
+
|
5
|
+
from janito.cli.config import config
|
6
|
+
import janito.i18n as i18n
|
7
|
+
from janito.cli.console import shared_console
|
8
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
9
|
+
|
10
|
+
|
11
|
+
class LangShellHandler(ShellCmdHandler):
|
12
|
+
help_text = "Change the interface language (e.g., /lang en)"
|
13
|
+
|
14
|
+
def run(self):
|
15
|
+
lang_code = self.after_cmd_line.strip()
|
16
|
+
if not lang_code:
|
17
|
+
shared_console.print(
|
18
|
+
"[bold yellow]Uso: /lang [código_idioma] (ex: pt, en, es)[/bold yellow]"
|
19
|
+
)
|
20
|
+
return
|
21
|
+
config.runtime_set("lang", lang_code)
|
22
|
+
i18n.set_locale(lang_code)
|
23
|
+
shared_console.print(
|
24
|
+
f"[bold green]Idioma alterado para:[/bold green] [cyan]{lang_code}[/cyan]"
|
25
|
+
)
|
@@ -0,0 +1,137 @@
|
|
1
|
+
from janito.performance_collector import PerformanceCollector
|
2
|
+
from rich.tree import Tree
|
3
|
+
from rich.console import Console
|
4
|
+
from rich import print as rprint
|
5
|
+
import datetime
|
6
|
+
|
7
|
+
# TODO: Replace this with your actual collector instance retrieval
|
8
|
+
# For example, if you have a global or singleton:
|
9
|
+
# from janito.app_context import performance_collector as collector
|
10
|
+
from janito.perf_singleton import performance_collector as collector
|
11
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
12
|
+
from janito.cli.console import shared_console
|
13
|
+
|
14
|
+
|
15
|
+
def _event_timestamp(event):
|
16
|
+
if hasattr(event, "timestamp"):
|
17
|
+
try:
|
18
|
+
ts = float(getattr(event, "timestamp", 0))
|
19
|
+
return f" [dim]{datetime.datetime.fromtimestamp(ts)}[/dim]"
|
20
|
+
except Exception:
|
21
|
+
return ""
|
22
|
+
return ""
|
23
|
+
|
24
|
+
|
25
|
+
def _event_tool_name(event):
|
26
|
+
return (
|
27
|
+
f" [cyan]{getattr(event, 'tool_name', '')}[/cyan]"
|
28
|
+
if hasattr(event, "tool_name")
|
29
|
+
else ""
|
30
|
+
)
|
31
|
+
|
32
|
+
|
33
|
+
def _event_params(event):
|
34
|
+
return (
|
35
|
+
f" Params: {getattr(event, 'params', '')}" if hasattr(event, "params") else ""
|
36
|
+
)
|
37
|
+
|
38
|
+
|
39
|
+
def _event_result(event):
|
40
|
+
return (
|
41
|
+
f" Result: {getattr(event, 'result', '')}" if hasattr(event, "result") else ""
|
42
|
+
)
|
43
|
+
|
44
|
+
|
45
|
+
def _event_error(event):
|
46
|
+
return (
|
47
|
+
f" [red]Error: {getattr(event, 'error')}[/red]"
|
48
|
+
if hasattr(event, "error") and getattr(event, "error", None)
|
49
|
+
else ""
|
50
|
+
)
|
51
|
+
|
52
|
+
|
53
|
+
def _event_message(event):
|
54
|
+
return (
|
55
|
+
f" [yellow]Message: {getattr(event, 'message')}[/yellow]"
|
56
|
+
if hasattr(event, "message")
|
57
|
+
else ""
|
58
|
+
)
|
59
|
+
|
60
|
+
|
61
|
+
def _event_subtype(event):
|
62
|
+
return (
|
63
|
+
f" [magenta]Subtype: {getattr(event, 'subtype')}[/magenta]"
|
64
|
+
if hasattr(event, "subtype")
|
65
|
+
else ""
|
66
|
+
)
|
67
|
+
|
68
|
+
|
69
|
+
def _event_status(event):
|
70
|
+
return (
|
71
|
+
f" [blue]Status: {getattr(event, 'status')}[/blue]"
|
72
|
+
if hasattr(event, "status")
|
73
|
+
else ""
|
74
|
+
)
|
75
|
+
|
76
|
+
|
77
|
+
def _event_duration(event):
|
78
|
+
return (
|
79
|
+
f" [green]Duration: {getattr(event, 'duration')}[/green]"
|
80
|
+
if hasattr(event, "duration")
|
81
|
+
else ""
|
82
|
+
)
|
83
|
+
|
84
|
+
|
85
|
+
def format_event(event_tuple, parent_tree=None):
|
86
|
+
event_type, event = event_tuple
|
87
|
+
desc = f"[bold]{event_type}[/bold]"
|
88
|
+
# Modular logic for each possible component
|
89
|
+
desc += _event_timestamp(event)
|
90
|
+
desc += _event_tool_name(event)
|
91
|
+
desc += _event_params(event)
|
92
|
+
desc += _event_result(event)
|
93
|
+
desc += _event_error(event)
|
94
|
+
desc += _event_message(event)
|
95
|
+
desc += _event_subtype(event)
|
96
|
+
desc += _event_status(event)
|
97
|
+
desc += _event_duration(event)
|
98
|
+
if parent_tree is not None:
|
99
|
+
node = parent_tree.add(desc)
|
100
|
+
else:
|
101
|
+
node = Tree(desc)
|
102
|
+
return node
|
103
|
+
|
104
|
+
|
105
|
+
def drill_down_last_generation():
|
106
|
+
events = collector.get_all_events()
|
107
|
+
# Find the last RequestStarted
|
108
|
+
last_gen_start = None
|
109
|
+
for i in range(len(events) - 1, -1, -1):
|
110
|
+
if events[i][0] == "RequestStarted":
|
111
|
+
last_gen_start = i
|
112
|
+
break
|
113
|
+
if last_gen_start is None:
|
114
|
+
rprint("[red]No generations found.[/red]")
|
115
|
+
return
|
116
|
+
# Find the next GenerationFinished after last_gen_start
|
117
|
+
for j in range(last_gen_start + 1, len(events)):
|
118
|
+
if events[j][0] == "GenerationFinished":
|
119
|
+
last_gen_end = j
|
120
|
+
break
|
121
|
+
else:
|
122
|
+
last_gen_end = len(events) - 1
|
123
|
+
gen_events = events[last_gen_start : last_gen_end + 1]
|
124
|
+
tree = Tree("[bold green]Last Generation Details[/bold green]")
|
125
|
+
for evt in gen_events:
|
126
|
+
format_event(evt, tree)
|
127
|
+
console = Console()
|
128
|
+
console.print(tree)
|
129
|
+
|
130
|
+
|
131
|
+
class LastShellHandler(ShellCmdHandler):
|
132
|
+
help_text = (
|
133
|
+
"Show details of the last generation, with drill-down of tool executions."
|
134
|
+
)
|
135
|
+
|
136
|
+
def run(self):
|
137
|
+
drill_down_last_generation()
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
|
4
|
+
|
5
|
+
class LivelogsShellHandler(ShellCmdHandler):
|
6
|
+
help_text = "Show the last lines of livereload logs. Usage: /livelogs [lines]"
|
7
|
+
|
8
|
+
def run(self):
|
9
|
+
lines_arg = self.after_cmd_line.strip()
|
10
|
+
lines = 20
|
11
|
+
if lines_arg and lines_arg.isdigit():
|
12
|
+
lines = int(lines_arg)
|
13
|
+
stdout_path = self.shell_state.termweb_stdout_path if self.shell_state else None
|
14
|
+
stderr_path = (
|
15
|
+
self.shell_state.livereload_stderr_path if self.shell_state else None
|
16
|
+
)
|
17
|
+
if not stdout_path and not stderr_path:
|
18
|
+
shared_console.print(
|
19
|
+
"[yellow][livereload] No livereload log files found for this session.[/yellow]"
|
20
|
+
)
|
21
|
+
return
|
22
|
+
stdout_lines = []
|
23
|
+
stderr_lines = []
|
24
|
+
if stdout_path:
|
25
|
+
try:
|
26
|
+
with open(stdout_path, encoding="utf-8") as f:
|
27
|
+
stdout_lines = f.readlines()[-lines:]
|
28
|
+
if stdout_lines:
|
29
|
+
shared_console.print(
|
30
|
+
f"[yellow][livereload][stdout] Tail of {stdout_path}:\n"
|
31
|
+
+ "".join(stdout_lines)
|
32
|
+
)
|
33
|
+
except Exception as e:
|
34
|
+
shared_console.print(f"[red][livereload][stdout] Error: {e}[/red]")
|
35
|
+
if stderr_path:
|
36
|
+
try:
|
37
|
+
with open(stderr_path, encoding="utf-8") as f:
|
38
|
+
stderr_lines = f.readlines()[-lines:]
|
39
|
+
if stderr_lines:
|
40
|
+
shared_console.print(
|
41
|
+
f"[red][livereload][stderr] Tail of {stderr_path}:\n"
|
42
|
+
+ "".join(stderr_lines)
|
43
|
+
)
|
44
|
+
except Exception as e:
|
45
|
+
shared_console.print(f"[red][livereload][stderr] Error: {e}[/red]")
|
46
|
+
if (not stdout_path or not stdout_lines) and (
|
47
|
+
not stderr_path or not stderr_lines
|
48
|
+
):
|
49
|
+
shared_console.print("[livereload] No output or errors captured in logs.")
|
@@ -0,0 +1,51 @@
|
|
1
|
+
from prompt_toolkit.shortcuts import prompt
|
2
|
+
from prompt_toolkit.application.current import get_app
|
3
|
+
from prompt_toolkit.document import Document
|
4
|
+
from prompt_toolkit.key_binding import KeyBindings
|
5
|
+
from janito.cli.console import shared_console
|
6
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
7
|
+
|
8
|
+
|
9
|
+
class MultiShellHandler(ShellCmdHandler):
|
10
|
+
help_text = "Prompt for multi-line input and display the result. Usage: /multi"
|
11
|
+
|
12
|
+
def run(self):
|
13
|
+
shared_console.print(
|
14
|
+
"[bold blue]Entering multi-line input mode. Press Esc+Enter or Ctrl+D to submit, Ctrl+C to cancel.[/bold blue]"
|
15
|
+
)
|
16
|
+
# Prompt for multi-line input
|
17
|
+
bindings = KeyBindings()
|
18
|
+
submitted = {"value": None}
|
19
|
+
|
20
|
+
@bindings.add("escape", "enter")
|
21
|
+
def _(event):
|
22
|
+
buffer = event.app.current_buffer
|
23
|
+
submitted["value"] = buffer.text
|
24
|
+
event.app.exit(result=buffer.text)
|
25
|
+
|
26
|
+
# Support Ctrl+D
|
27
|
+
@bindings.add("c-d")
|
28
|
+
def _(event):
|
29
|
+
buffer = event.app.current_buffer
|
30
|
+
submitted["value"] = buffer.text
|
31
|
+
event.app.exit(result=buffer.text)
|
32
|
+
|
33
|
+
try:
|
34
|
+
user_input = prompt(
|
35
|
+
"Multi-line > ",
|
36
|
+
multiline=True,
|
37
|
+
key_bindings=bindings,
|
38
|
+
)
|
39
|
+
except (EOFError, KeyboardInterrupt):
|
40
|
+
shared_console.print("[red]Multi-line input cancelled.[/red]")
|
41
|
+
return
|
42
|
+
|
43
|
+
# Save input to history if available
|
44
|
+
user_input_history = getattr(self.shell_state, "user_input_history", None)
|
45
|
+
if user_input_history is not None:
|
46
|
+
user_input_history.append(user_input)
|
47
|
+
# Store input for main chat loop to consume as if just entered by the user
|
48
|
+
self.shell_state.injected_input = user_input
|
49
|
+
shared_console.print(
|
50
|
+
"[green]Multi-line input will be sent as your next chat prompt.[/green]"
|
51
|
+
)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
from janito.cli.config import config
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
from janito.cli.console import shared_console
|
4
|
+
|
5
|
+
|
6
|
+
class PromptShellHandler(ShellCmdHandler):
|
7
|
+
help_text = "Show the system prompt"
|
8
|
+
|
9
|
+
def run(self):
|
10
|
+
agent = getattr(self.shell_state, "agent", None)
|
11
|
+
if agent and hasattr(agent, "get_system_prompt"):
|
12
|
+
prompt = agent.get_system_prompt()
|
13
|
+
shared_console.print(
|
14
|
+
f"[bold magenta]System Prompt:[/bold magenta]\n{prompt}"
|
15
|
+
)
|
16
|
+
else:
|
17
|
+
shared_console.print(
|
18
|
+
"[bold red]No LLM agent available to fetch the system prompt.[/bold red]"
|
19
|
+
)
|
20
|
+
|
21
|
+
|
22
|
+
class RoleShellHandler(ShellCmdHandler):
|
23
|
+
help_text = "Change the system role"
|
24
|
+
|
25
|
+
def run(self):
|
26
|
+
new_role = self.after_cmd_line.strip()
|
27
|
+
if not new_role:
|
28
|
+
agent = getattr(self.shell_state, "agent", None)
|
29
|
+
if agent and hasattr(agent, "template_vars"):
|
30
|
+
current_role = agent.template_vars.get("role", None)
|
31
|
+
else:
|
32
|
+
current_role = None
|
33
|
+
if not current_role:
|
34
|
+
current_role = "<not set>"
|
35
|
+
shared_console.print(
|
36
|
+
f"[bold green]Current system role:[/bold green] {current_role}"
|
37
|
+
)
|
38
|
+
return
|
39
|
+
|
40
|
+
agent = getattr(self.shell_state, "agent", None)
|
41
|
+
if agent and hasattr(agent, "set_template_var"):
|
42
|
+
agent.set_template_var("role", new_role)
|
43
|
+
# Refresh the system prompt with the new role if possible
|
44
|
+
if (
|
45
|
+
hasattr(agent, "set_system_using_template")
|
46
|
+
and hasattr(agent, "_system_prompt_template_file")
|
47
|
+
and agent._system_prompt_template_file
|
48
|
+
):
|
49
|
+
agent.set_system_using_template(
|
50
|
+
agent._system_prompt_template_file, **agent.template_vars
|
51
|
+
)
|
52
|
+
shared_console.print(
|
53
|
+
f"[bold green]System role updated to:[/bold green] {new_role}"
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
class ProfileShellHandler(ShellCmdHandler):
|
58
|
+
help_text = (
|
59
|
+
"Show the current and available Agent Profile (only 'base' is supported)"
|
60
|
+
)
|
61
|
+
|
62
|
+
def run(self):
|
63
|
+
shared_console.print("[bold green]Current profile:[/bold green] base")
|
64
|
+
shared_console.print("[bold yellow]Available profiles:[/bold yellow]\n- base")
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
2
|
+
|
3
|
+
|
4
|
+
class RoleCommandShellHandler(ShellCmdHandler):
|
5
|
+
"""Set or display the current role."""
|
6
|
+
|
7
|
+
def __init__(self, shell_state, handler):
|
8
|
+
super().__init__(shell_state, handler)
|
9
|
+
self.name = "role"
|
10
|
+
self.description = "Set or display the current role"
|
11
|
+
self.usage = "role [new_role]"
|
12
|
+
|
13
|
+
def execute(self, args):
|
14
|
+
if not args:
|
15
|
+
# Display current role
|
16
|
+
current_role = self.handler.agent.template_vars.get("role", "default")
|
17
|
+
return f"Current role: {current_role}"
|
18
|
+
else:
|
19
|
+
# Set new role
|
20
|
+
new_role = " ".join(args)
|
21
|
+
self.handler.agent.template_vars["role"] = new_role
|
22
|
+
# Refresh the system prompt with the new role if possible
|
23
|
+
if (
|
24
|
+
hasattr(self.handler.agent, "set_system_using_template")
|
25
|
+
and hasattr(self.handler.agent, "_system_prompt_template_file")
|
26
|
+
and self.handler.agent._system_prompt_template_file
|
27
|
+
):
|
28
|
+
self.handler.agent.set_system_using_template(
|
29
|
+
self.handler.agent._system_prompt_template_file,
|
30
|
+
**self.handler.agent.template_vars,
|
31
|
+
)
|
32
|
+
return f"Role set to: {new_role}"
|
33
|
+
|
34
|
+
def get_completions(self, document, complete_event):
|
35
|
+
# No completions for this command
|
36
|
+
return []
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
|
3
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
4
|
+
from janito.cli.console import shared_console
|
5
|
+
|
6
|
+
|
7
|
+
class HistoryShellHandler(ShellCmdHandler):
|
8
|
+
help_text = "Show input history for this session"
|
9
|
+
|
10
|
+
def run(self):
|
11
|
+
if self.shell_state and hasattr(self.shell_state, "mem_history"):
|
12
|
+
input_history = list(self.shell_state.mem_history.get_strings())
|
13
|
+
else:
|
14
|
+
input_history = []
|
15
|
+
args = self.after_cmd_line.strip().split()
|
16
|
+
if not args:
|
17
|
+
start = max(0, len(input_history) - 5)
|
18
|
+
end = len(input_history)
|
19
|
+
elif len(args) == 1:
|
20
|
+
count = int(args[0])
|
21
|
+
start = max(0, len(input_history) - count)
|
22
|
+
end = len(input_history)
|
23
|
+
elif len(args) >= 2:
|
24
|
+
start = int(args[0])
|
25
|
+
end = int(args[1]) + 1
|
26
|
+
else:
|
27
|
+
start = 0
|
28
|
+
end = len(input_history)
|
29
|
+
shared_console.print(
|
30
|
+
f"[bold cyan]Showing input history {start} to {end - 1} (total {len(input_history)}):[/bold cyan]"
|
31
|
+
)
|
32
|
+
for idx, line in enumerate(input_history[start:end], start=start):
|
33
|
+
shared_console.print(f"{idx}: {line}")
|
34
|
+
if isinstance(line, dict):
|
35
|
+
role = line.get("role", "unknown")
|
36
|
+
content = line.get("content", "")
|
37
|
+
else:
|
38
|
+
role = "user"
|
39
|
+
content = line
|
40
|
+
shared_console.print(f"[bold]{idx} [{role}]:[/bold] {content}")
|
@@ -6,7 +6,7 @@ import subprocess
|
|
6
6
|
def restart_cli():
|
7
7
|
# Clean up prompt_toolkit session if active
|
8
8
|
try:
|
9
|
-
from janito.
|
9
|
+
from janito.cli.chat_mode import chat_mode as main
|
10
10
|
|
11
11
|
session = getattr(main, "active_prompt_session", None)
|
12
12
|
if session is not None and hasattr(session, "app"):
|
@@ -37,7 +37,7 @@ def restart_cli():
|
|
37
37
|
os.execv(sys.executable, [sys.executable, "-m", "janito"] + sys.argv[1:])
|
38
38
|
|
39
39
|
|
40
|
-
def handle_exit(
|
40
|
+
def handle_exit(**kwargs):
|
41
41
|
console.print("[bold red]Exiting chat mode.[/bold red]")
|
42
42
|
sys.exit(0)
|
43
43
|
|