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,42 +0,0 @@
|
|
1
|
-
def handle_livelogs(console, args=None, shell_state=None, **kwargs):
|
2
|
-
lines = 20
|
3
|
-
if args and len(args) > 0 and str(args[0]).isdigit():
|
4
|
-
lines = int(args[0])
|
5
|
-
stdout_path = shell_state.termweb_stdout_path if shell_state else None
|
6
|
-
stderr_path = shell_state.livereload_stderr_path if shell_state else None
|
7
|
-
if not stdout_path and not stderr_path:
|
8
|
-
console.print(
|
9
|
-
"[yellow][livereload] No livereload log files found for this session.[/yellow]"
|
10
|
-
)
|
11
|
-
return
|
12
|
-
stdout_lines = []
|
13
|
-
stderr_lines = []
|
14
|
-
if stdout_path:
|
15
|
-
try:
|
16
|
-
with open(stdout_path, encoding="utf-8") as f:
|
17
|
-
stdout_lines = f.readlines()[-lines:]
|
18
|
-
if stdout_lines:
|
19
|
-
console.print(
|
20
|
-
f"[yellow][livereload][stdout] Tail of {stdout_path}:\n"
|
21
|
-
+ "".join(stdout_lines)
|
22
|
-
)
|
23
|
-
except Exception as e:
|
24
|
-
console.print(f"[red][livereload][stdout] Error: {e}[/red]")
|
25
|
-
if stderr_path:
|
26
|
-
try:
|
27
|
-
with open(stderr_path, encoding="utf-8") as f:
|
28
|
-
stderr_lines = f.readlines()[-lines:]
|
29
|
-
if stderr_lines:
|
30
|
-
console.print(
|
31
|
-
f"[red][livereload][stderr] Tail of {stderr_path}:\n"
|
32
|
-
+ "".join(stderr_lines)
|
33
|
-
)
|
34
|
-
except Exception as e:
|
35
|
-
console.print(f"[red][livereload][stderr] Error: {e}[/red]")
|
36
|
-
if (not stdout_path or not stdout_lines) and (not stderr_path or not stderr_lines):
|
37
|
-
console.print("[livereload] No output or errors captured in logs.")
|
38
|
-
|
39
|
-
|
40
|
-
handle_livelogs.help_text = (
|
41
|
-
"Show live updates from the server log file (default: server.log)"
|
42
|
-
)
|
janito/shell/commands/prompt.py
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
from janito.agent.runtime_config import runtime_config
|
2
|
-
|
3
|
-
|
4
|
-
def handle_prompt(console, shell_state=None, **kwargs):
|
5
|
-
profile_manager = kwargs.get("profile_manager")
|
6
|
-
if not profile_manager and shell_state and hasattr(shell_state, "profile_manager"):
|
7
|
-
profile_manager = shell_state.profile_manager
|
8
|
-
prompt = None
|
9
|
-
if profile_manager:
|
10
|
-
prompt = profile_manager.system_prompt_template
|
11
|
-
if not prompt:
|
12
|
-
profile_manager.refresh_prompt()
|
13
|
-
prompt = profile_manager.system_prompt_template
|
14
|
-
if not prompt:
|
15
|
-
console.print(
|
16
|
-
"[bold red]System prompt is not initialized. Please check your profile configuration.[/bold red]"
|
17
|
-
)
|
18
|
-
else:
|
19
|
-
console.print(f"[bold magenta]System Prompt:[/bold magenta]\n{prompt}")
|
20
|
-
|
21
|
-
|
22
|
-
handle_prompt.help_text = "Show the system prompt"
|
23
|
-
|
24
|
-
|
25
|
-
def handle_role(console, args=None, shell_state=None, **kwargs):
|
26
|
-
profile_manager = (
|
27
|
-
shell_state.profile_manager
|
28
|
-
if shell_state and hasattr(shell_state, "profile_manager")
|
29
|
-
else kwargs.get("profile_manager")
|
30
|
-
)
|
31
|
-
if not args:
|
32
|
-
console.print("[bold red]Usage: /role <new role description>[/bold red]")
|
33
|
-
return
|
34
|
-
new_role = " ".join(args)
|
35
|
-
if profile_manager:
|
36
|
-
profile_manager.set_role(new_role)
|
37
|
-
# Update system message in conversation
|
38
|
-
found = False
|
39
|
-
for msg in shell_state.conversation_history.get_messages():
|
40
|
-
if msg.get("role") == "system":
|
41
|
-
msg["content"] = (
|
42
|
-
profile_manager.system_prompt_template if profile_manager else new_role
|
43
|
-
)
|
44
|
-
found = True
|
45
|
-
break
|
46
|
-
if not found:
|
47
|
-
if shell_state and hasattr(shell_state, "conversation_history"):
|
48
|
-
shell_state.conversation_history.set_system_message(new_role)
|
49
|
-
# Also store the raw role string
|
50
|
-
if profile_manager:
|
51
|
-
setattr(profile_manager, "role_name", new_role)
|
52
|
-
runtime_config.set("role", new_role)
|
53
|
-
console.print(f"[bold green]System role updated to:[/bold green] {new_role}")
|
54
|
-
|
55
|
-
|
56
|
-
handle_role.help_text = "Change the system role"
|
57
|
-
|
58
|
-
|
59
|
-
def handle_profile(console, *args, **kwargs):
|
60
|
-
"""/profile - Show the current and available Agent Profile (only 'base' is supported)"""
|
61
|
-
console.print("[bold green]Current profile:[/bold green] base")
|
62
|
-
console.print("[bold yellow]Available profiles:[/bold yellow]\n- base")
|
@@ -1,94 +0,0 @@
|
|
1
|
-
import http.client
|
2
|
-
from rich.console import Console
|
3
|
-
from janito.agent.runtime_config import runtime_config
|
4
|
-
|
5
|
-
|
6
|
-
def is_termweb_running(port):
|
7
|
-
"""Check if termweb is running by making an HTTP request to the root endpoint."""
|
8
|
-
try:
|
9
|
-
conn = http.client.HTTPConnection("localhost", port, timeout=0.5)
|
10
|
-
conn.request("GET", "/")
|
11
|
-
resp = conn.getresponse()
|
12
|
-
return resp.status == 200
|
13
|
-
except Exception:
|
14
|
-
return False
|
15
|
-
|
16
|
-
|
17
|
-
def handle_termweb_log_tail(console: Console, *args, shell_state=None, **kwargs):
|
18
|
-
lines = 20
|
19
|
-
if args and args[0].isdigit():
|
20
|
-
lines = int(args[0])
|
21
|
-
stdout_path = shell_state.termweb_stdout_path if shell_state else None
|
22
|
-
stderr_path = shell_state.termweb_stderr_path if shell_state else None
|
23
|
-
if not stdout_path and not stderr_path:
|
24
|
-
console.print(
|
25
|
-
"[yellow][termweb] No termweb log files found for this session.[/yellow]"
|
26
|
-
)
|
27
|
-
return
|
28
|
-
if stdout_path:
|
29
|
-
try:
|
30
|
-
with open(stdout_path, encoding="utf-8") as f:
|
31
|
-
stdout_lines = f.readlines()[-lines:]
|
32
|
-
if stdout_lines:
|
33
|
-
console.print(
|
34
|
-
f"[yellow][termweb][stdout] Tail of {stdout_path}:\n"
|
35
|
-
+ "".join(stdout_lines)
|
36
|
-
)
|
37
|
-
except Exception:
|
38
|
-
pass
|
39
|
-
if stderr_path:
|
40
|
-
try:
|
41
|
-
with open(stderr_path, encoding="utf-8") as f:
|
42
|
-
stderr_lines = f.readlines()[-lines:]
|
43
|
-
if stderr_lines:
|
44
|
-
console.print(
|
45
|
-
f"[red][termweb][stderr] Tail of {stderr_path}:\n"
|
46
|
-
+ "".join(stderr_lines)
|
47
|
-
)
|
48
|
-
except Exception:
|
49
|
-
pass
|
50
|
-
if (not stdout_path or not stdout_lines) and (not stderr_path or not stderr_lines):
|
51
|
-
console.print("[termweb] No output or errors captured in logs.")
|
52
|
-
|
53
|
-
|
54
|
-
handle_termweb_log_tail.help_text = "Show the last lines of the latest termweb logs"
|
55
|
-
|
56
|
-
|
57
|
-
def handle_termweb_status(console: Console, *args, shell_state=None, **kwargs):
|
58
|
-
if shell_state is None:
|
59
|
-
console.print(
|
60
|
-
"[red]No shell state available. Cannot determine termweb status.[/red]"
|
61
|
-
)
|
62
|
-
return
|
63
|
-
port = getattr(shell_state, "termweb_port", None)
|
64
|
-
port_source = "shell_state"
|
65
|
-
if not port:
|
66
|
-
port = runtime_config.get("termweb_port")
|
67
|
-
port_source = "runtime_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:
|
73
|
-
running = is_termweb_running(port)
|
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(
|
84
|
-
" [yellow]No port configured in state or runtime_config.[/yellow]"
|
85
|
-
)
|
86
|
-
if stdout_path:
|
87
|
-
console.print(f" Stdout log: {stdout_path}")
|
88
|
-
if stderr_path:
|
89
|
-
console.print(f" Stderr log: {stderr_path}")
|
90
|
-
|
91
|
-
|
92
|
-
handle_termweb_status.help_text = (
|
93
|
-
"Show status information about the running termweb server"
|
94
|
-
)
|
janito/shell/commands/tools.py
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
from janito.agent.tool_registry import get_tool_schemas
|
2
|
-
from rich.table import Table
|
3
|
-
|
4
|
-
|
5
|
-
def handle_tools(console, args=None, shell_state=None):
|
6
|
-
table = Table(title="Available Tools", show_lines=True, style="bold magenta")
|
7
|
-
table.add_column("Name", style="cyan", no_wrap=True)
|
8
|
-
table.add_column("Description", style="green")
|
9
|
-
table.add_column("Parameters", style="yellow")
|
10
|
-
try:
|
11
|
-
for schema in get_tool_schemas():
|
12
|
-
fn = schema["function"]
|
13
|
-
params = "\n".join(
|
14
|
-
[
|
15
|
-
f"[bold]{k}[/]: {v['type']}"
|
16
|
-
for k, v in fn["parameters"].get("properties", {}).items()
|
17
|
-
]
|
18
|
-
)
|
19
|
-
table.add_row(f"[b]{fn['name']}[/b]", fn["description"], params or "-")
|
20
|
-
except Exception as e:
|
21
|
-
console.print(f"[red]Error loading tools: {e}[/red]")
|
22
|
-
return
|
23
|
-
console.print(table)
|
24
|
-
|
25
|
-
|
26
|
-
handle_tools.help_text = "List available tools"
|
janito/shell/commands/track.py
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
from janito.agent.tool_use_tracker import ToolUseTracker
|
2
|
-
from rich.console import Console
|
3
|
-
from rich.table import Table
|
4
|
-
|
5
|
-
|
6
|
-
def handle_track(console: Console, args=None, shell_state=None):
|
7
|
-
tracker = ToolUseTracker.instance()
|
8
|
-
history = tracker.get_history()
|
9
|
-
if not history:
|
10
|
-
console.print("[bold yellow]No tool usage history found.[/bold yellow]")
|
11
|
-
return
|
12
|
-
table = Table(show_header=True, header_style="bold magenta")
|
13
|
-
table.add_column("#", style="dim", width=4)
|
14
|
-
table.add_column("Tool")
|
15
|
-
table.add_column("Params/Result")
|
16
|
-
for idx, entry in enumerate(history, 1):
|
17
|
-
tool = entry["tool"]
|
18
|
-
params = entry["params"].copy()
|
19
|
-
result = entry.get("result", "")
|
20
|
-
# For create/replace file, trim content in params only
|
21
|
-
if tool in ("create_file", "replace_file") and "content" in params:
|
22
|
-
content = params["content"]
|
23
|
-
if isinstance(content, str):
|
24
|
-
lines = content.splitlines()
|
25
|
-
if len(lines) > 3:
|
26
|
-
params["content"] = (
|
27
|
-
"\n".join(lines[:2])
|
28
|
-
+ f"\n... (trimmed, {len(lines)} lines total)"
|
29
|
-
)
|
30
|
-
elif len(content) > 120:
|
31
|
-
params["content"] = content[:120] + "... (trimmed)"
|
32
|
-
else:
|
33
|
-
params["content"] = content
|
34
|
-
param_result = f"{params}\n--- Result ---\n{result}" if result else str(params)
|
35
|
-
table.add_row(str(idx), tool, param_result)
|
36
|
-
console.print(table)
|
janito/shell/main.py
DELETED
@@ -1,326 +0,0 @@
|
|
1
|
-
from janito.agent.rich_message_handler import RichMessageHandler
|
2
|
-
from prompt_toolkit.history import InMemoryHistory
|
3
|
-
from dataclasses import dataclass, field
|
4
|
-
from typing import Optional, Any, Dict
|
5
|
-
from janito.shell.prompt.session_setup import (
|
6
|
-
setup_prompt_session,
|
7
|
-
print_welcome_message,
|
8
|
-
)
|
9
|
-
from janito.shell.commands import handle_command
|
10
|
-
from janito.agent.conversation_exceptions import EmptyResponseError, ProviderError
|
11
|
-
from janito.agent.api_exceptions import ApiError
|
12
|
-
from janito.agent.llm_conversation_history import LLMConversationHistory
|
13
|
-
import janito.i18n as i18n
|
14
|
-
from janito.agent.runtime_config import runtime_config
|
15
|
-
from rich.console import Console
|
16
|
-
import os
|
17
|
-
from janito.shell.session.manager import get_session_id
|
18
|
-
from prompt_toolkit.formatted_text import HTML
|
19
|
-
import time
|
20
|
-
from janito.shell.input_history import UserInputHistory
|
21
|
-
|
22
|
-
|
23
|
-
@dataclass
|
24
|
-
class ShellState:
|
25
|
-
mem_history: Any = field(default_factory=InMemoryHistory)
|
26
|
-
conversation_history: Any = field(default_factory=lambda: LLMConversationHistory())
|
27
|
-
last_usage_info: Dict[str, int] = field(
|
28
|
-
default_factory=lambda: {
|
29
|
-
"prompt_tokens": 0,
|
30
|
-
"completion_tokens": 0,
|
31
|
-
"total_tokens": 0,
|
32
|
-
}
|
33
|
-
)
|
34
|
-
last_elapsed: Optional[float] = None
|
35
|
-
termweb_stdout_path: Optional[str] = None
|
36
|
-
termweb_stderr_path: Optional[str] = None
|
37
|
-
livereload_stdout_path: Optional[str] = None
|
38
|
-
livereload_stderr_path: Optional[str] = None
|
39
|
-
paste_mode: bool = False
|
40
|
-
profile_manager: Optional[Any] = None
|
41
|
-
user_input_history: Optional[Any] = None
|
42
|
-
|
43
|
-
|
44
|
-
# Track the active prompt session for cleanup
|
45
|
-
active_prompt_session = None
|
46
|
-
|
47
|
-
|
48
|
-
def load_session(shell_state, continue_session, session_id, profile_manager):
|
49
|
-
from janito.shell.session.manager import load_conversation_by_session_id
|
50
|
-
|
51
|
-
if continue_session and session_id:
|
52
|
-
try:
|
53
|
-
messages, prompts, usage = load_conversation_by_session_id(session_id)
|
54
|
-
except FileNotFoundError as e:
|
55
|
-
shell_state.profile_manager.agent.message_handler.console.print(
|
56
|
-
f"[bold red]{str(e)}[/bold red]"
|
57
|
-
)
|
58
|
-
return False
|
59
|
-
shell_state.conversation_history = LLMConversationHistory(messages)
|
60
|
-
conversation_history = shell_state.conversation_history
|
61
|
-
found = False
|
62
|
-
for msg in conversation_history.get_messages():
|
63
|
-
if msg.get("role") == "system":
|
64
|
-
msg["content"] = profile_manager.system_prompt_template
|
65
|
-
found = True
|
66
|
-
break
|
67
|
-
if not found:
|
68
|
-
conversation_history.set_system_message(
|
69
|
-
profile_manager.system_prompt_template
|
70
|
-
)
|
71
|
-
shell_state.last_usage_info = usage or {}
|
72
|
-
else:
|
73
|
-
conversation_history = shell_state.conversation_history
|
74
|
-
if (
|
75
|
-
profile_manager.system_prompt_template
|
76
|
-
and (
|
77
|
-
not runtime_config.get("vanilla_mode", False)
|
78
|
-
or runtime_config.get("system_prompt_template")
|
79
|
-
)
|
80
|
-
and not any(
|
81
|
-
m.get("role") == "system" for m in conversation_history.get_messages()
|
82
|
-
)
|
83
|
-
):
|
84
|
-
conversation_history.set_system_message(
|
85
|
-
profile_manager.system_prompt_template
|
86
|
-
)
|
87
|
-
return True
|
88
|
-
|
89
|
-
|
90
|
-
def _handle_exit_confirmation(session, message_handler, conversation_history):
|
91
|
-
try:
|
92
|
-
confirm = (
|
93
|
-
session.prompt(
|
94
|
-
HTML("<inputline>Do you really want to exit? (y/n): </inputline>")
|
95
|
-
)
|
96
|
-
.strip()
|
97
|
-
.lower()
|
98
|
-
)
|
99
|
-
except KeyboardInterrupt:
|
100
|
-
message_handler.handle_message({"type": "error", "message": "Exiting..."})
|
101
|
-
return True
|
102
|
-
if confirm == "y":
|
103
|
-
message_handler.handle_message({"type": "error", "message": "Exiting..."})
|
104
|
-
conversation_history.add_message(
|
105
|
-
{"role": "system", "content": "[Session ended by user]"}
|
106
|
-
)
|
107
|
-
return True
|
108
|
-
return False
|
109
|
-
|
110
|
-
|
111
|
-
def _handle_shell_command(user_input, console):
|
112
|
-
command = user_input.strip()[1:].strip()
|
113
|
-
if command:
|
114
|
-
console.print(f"[bold cyan]Executing shell command:[/] {command}")
|
115
|
-
exit_code = os.system(command)
|
116
|
-
console.print(f"[green]Command exited with code {exit_code}[/green]")
|
117
|
-
else:
|
118
|
-
console.print("[red]No command provided after ![/red]")
|
119
|
-
|
120
|
-
|
121
|
-
def _handle_prompt_command(user_input, console, shell_state, conversation_history):
|
122
|
-
result = handle_command(
|
123
|
-
user_input.strip(),
|
124
|
-
console,
|
125
|
-
shell_state=shell_state,
|
126
|
-
)
|
127
|
-
if result == "exit":
|
128
|
-
conversation_history.add_message(
|
129
|
-
{"role": "system", "content": "[Session ended by user]"}
|
130
|
-
)
|
131
|
-
return True
|
132
|
-
return False
|
133
|
-
|
134
|
-
|
135
|
-
def handle_prompt_loop(
|
136
|
-
shell_state, session, profile_manager, agent, max_rounds, session_id
|
137
|
-
):
|
138
|
-
global active_prompt_session
|
139
|
-
conversation_history = shell_state.conversation_history
|
140
|
-
message_handler = RichMessageHandler()
|
141
|
-
console = message_handler.console
|
142
|
-
while True:
|
143
|
-
try:
|
144
|
-
if shell_state.paste_mode:
|
145
|
-
user_input = session.prompt("Multiline> ", multiline=True)
|
146
|
-
was_paste_mode = True
|
147
|
-
shell_state.paste_mode = False
|
148
|
-
else:
|
149
|
-
user_input = session.prompt(
|
150
|
-
HTML("<inputline>💬 </inputline>"), multiline=False
|
151
|
-
)
|
152
|
-
was_paste_mode = False
|
153
|
-
except EOFError:
|
154
|
-
console.print("\n[bold red]Exiting...[/bold red]")
|
155
|
-
break
|
156
|
-
except KeyboardInterrupt:
|
157
|
-
console.print()
|
158
|
-
if _handle_exit_confirmation(
|
159
|
-
session, message_handler, conversation_history
|
160
|
-
):
|
161
|
-
break
|
162
|
-
else:
|
163
|
-
continue
|
164
|
-
# Handle !cmd command: execute shell command with os.system
|
165
|
-
if user_input.strip().startswith("!"):
|
166
|
-
_handle_shell_command(user_input, console)
|
167
|
-
continue
|
168
|
-
|
169
|
-
cmd_input = user_input.strip().lower()
|
170
|
-
if not was_paste_mode and (cmd_input.startswith("/") or cmd_input == "exit"):
|
171
|
-
if _handle_prompt_command(
|
172
|
-
user_input, console, shell_state, conversation_history
|
173
|
-
):
|
174
|
-
break
|
175
|
-
continue
|
176
|
-
if not user_input.strip():
|
177
|
-
continue
|
178
|
-
shell_state.mem_history.append_string(user_input)
|
179
|
-
shell_state.user_input_history.append(user_input)
|
180
|
-
conversation_history.add_message({"role": "user", "content": user_input})
|
181
|
-
handle_chat(shell_state, profile_manager, agent, max_rounds, session_id)
|
182
|
-
# Save conversation history after exiting
|
183
|
-
save_conversation_history(conversation_history, session_id)
|
184
|
-
|
185
|
-
|
186
|
-
def handle_keyboard_interrupt(conversation_history, message_handler):
|
187
|
-
removed_count = 0
|
188
|
-
while (
|
189
|
-
conversation_history.last_message()
|
190
|
-
and conversation_history.last_message().get("role") != "assistant"
|
191
|
-
):
|
192
|
-
conversation_history.remove_last_message()
|
193
|
-
removed_count += 1
|
194
|
-
# Remove the assistant message itself, if present
|
195
|
-
if (
|
196
|
-
conversation_history.last_message()
|
197
|
-
and conversation_history.last_message().get("role") == "assistant"
|
198
|
-
):
|
199
|
-
conversation_history.remove_last_message()
|
200
|
-
removed_count += 1
|
201
|
-
message_handler.handle_message(
|
202
|
-
{
|
203
|
-
"type": "info",
|
204
|
-
"message": f"\nLast turn cleared due to interruption. Returning to prompt. (removed {removed_count} last msgs)\n",
|
205
|
-
}
|
206
|
-
)
|
207
|
-
|
208
|
-
|
209
|
-
def handle_chat_error(message_handler, error_type, error):
|
210
|
-
if error_type == "ProviderError":
|
211
|
-
message_handler.handle_message(
|
212
|
-
{"type": "error", "message": f"Provider error: {error}"}
|
213
|
-
)
|
214
|
-
elif error_type == "EmptyResponseError":
|
215
|
-
message_handler.handle_message({"type": "error", "message": f"Error: {error}"})
|
216
|
-
elif error_type == "ApiError":
|
217
|
-
message_handler.handle_message({"type": "error", "message": str(error)})
|
218
|
-
elif error_type == "Exception":
|
219
|
-
import traceback
|
220
|
-
|
221
|
-
tb = traceback.format_exc()
|
222
|
-
message_handler.handle_message(
|
223
|
-
{
|
224
|
-
"type": "error",
|
225
|
-
"message": f"Unexpected error: {error}\n{tb}\nReturning to prompt.",
|
226
|
-
}
|
227
|
-
)
|
228
|
-
|
229
|
-
|
230
|
-
def handle_chat(shell_state, profile_manager, agent, max_rounds, session_id):
|
231
|
-
conversation_history = shell_state.conversation_history
|
232
|
-
message_handler = RichMessageHandler()
|
233
|
-
console = message_handler.console
|
234
|
-
start_time = time.time()
|
235
|
-
try:
|
236
|
-
response = profile_manager.agent.chat(
|
237
|
-
conversation_history,
|
238
|
-
max_rounds=max_rounds,
|
239
|
-
message_handler=message_handler,
|
240
|
-
spinner=True,
|
241
|
-
)
|
242
|
-
except KeyboardInterrupt:
|
243
|
-
handle_keyboard_interrupt(conversation_history, message_handler)
|
244
|
-
return
|
245
|
-
except ProviderError as e:
|
246
|
-
handle_chat_error(message_handler, "ProviderError", e)
|
247
|
-
return
|
248
|
-
except EmptyResponseError as e:
|
249
|
-
handle_chat_error(message_handler, "EmptyResponseError", e)
|
250
|
-
return
|
251
|
-
except ApiError as e:
|
252
|
-
handle_chat_error(message_handler, "ApiError", e)
|
253
|
-
return
|
254
|
-
except Exception as e:
|
255
|
-
handle_chat_error(message_handler, "Exception", e)
|
256
|
-
return
|
257
|
-
shell_state.last_elapsed = time.time() - start_time
|
258
|
-
usage = response.get("usage")
|
259
|
-
if usage:
|
260
|
-
for k in ("prompt_tokens", "completion_tokens", "total_tokens"):
|
261
|
-
shell_state.last_usage_info[k] = usage.get(k, 0)
|
262
|
-
content = response.get("content")
|
263
|
-
if content and (
|
264
|
-
len(conversation_history) == 0
|
265
|
-
or conversation_history.get_messages()[-1].get("role") != "assistant"
|
266
|
-
):
|
267
|
-
conversation_history.add_message({"role": "assistant", "content": content})
|
268
|
-
|
269
|
-
|
270
|
-
def save_conversation_history(conversation_history, session_id):
|
271
|
-
from janito.shell.session.manager import get_session_id
|
272
|
-
|
273
|
-
history_dir = os.path.join(os.path.expanduser("~"), ".janito", "chat_history")
|
274
|
-
os.makedirs(history_dir, exist_ok=True)
|
275
|
-
session_id_to_save = session_id if session_id else get_session_id()
|
276
|
-
history_path = os.path.join(history_dir, f"{session_id_to_save}.json")
|
277
|
-
conversation_history.to_json_file(history_path)
|
278
|
-
|
279
|
-
|
280
|
-
def start_chat_shell(
|
281
|
-
profile_manager,
|
282
|
-
continue_session=False,
|
283
|
-
session_id=None,
|
284
|
-
max_rounds=100,
|
285
|
-
termweb_stdout_path=None,
|
286
|
-
termweb_stderr_path=None,
|
287
|
-
livereload_stdout_path=None,
|
288
|
-
livereload_stderr_path=None,
|
289
|
-
):
|
290
|
-
i18n.set_locale(runtime_config.get("lang", "en"))
|
291
|
-
global active_prompt_session
|
292
|
-
agent = profile_manager.agent
|
293
|
-
message_handler = RichMessageHandler()
|
294
|
-
console = message_handler.console
|
295
|
-
console.clear()
|
296
|
-
shell_state = ShellState()
|
297
|
-
shell_state.profile_manager = profile_manager
|
298
|
-
profile_manager.refresh_prompt()
|
299
|
-
user_input_history = UserInputHistory()
|
300
|
-
user_input_dicts = user_input_history.load()
|
301
|
-
mem_history = shell_state.mem_history
|
302
|
-
for item in user_input_dicts:
|
303
|
-
if isinstance(item, dict) and "input" in item:
|
304
|
-
mem_history.append_string(item["input"])
|
305
|
-
shell_state.user_input_history = user_input_history
|
306
|
-
if not load_session(shell_state, continue_session, session_id, profile_manager):
|
307
|
-
return
|
308
|
-
|
309
|
-
def last_usage_info_ref():
|
310
|
-
return shell_state.last_usage_info
|
311
|
-
|
312
|
-
last_elapsed = shell_state.last_elapsed
|
313
|
-
print_welcome_message(console, continue_id=session_id if continue_session else None)
|
314
|
-
session = setup_prompt_session(
|
315
|
-
lambda: shell_state.conversation_history.get_messages(),
|
316
|
-
last_usage_info_ref,
|
317
|
-
last_elapsed,
|
318
|
-
mem_history,
|
319
|
-
profile_manager,
|
320
|
-
agent,
|
321
|
-
lambda: shell_state.conversation_history,
|
322
|
-
)
|
323
|
-
active_prompt_session = session
|
324
|
-
handle_prompt_loop(
|
325
|
-
shell_state, session, profile_manager, agent, max_rounds, session_id
|
326
|
-
)
|
@@ -1,57 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import importlib.resources
|
3
|
-
|
4
|
-
|
5
|
-
def load_prompt(filename=None):
|
6
|
-
"""
|
7
|
-
Load the system prompt from a file. If filename is None, use the default prompt file.
|
8
|
-
Returns the prompt string.
|
9
|
-
Tries source path first, then falls back to importlib.resources for installed packages.
|
10
|
-
"""
|
11
|
-
default_rel_path = os.path.normpath(
|
12
|
-
os.path.join(
|
13
|
-
os.path.dirname(__file__),
|
14
|
-
"../agent/templates/profiles/system_prompt_template_default.j2",
|
15
|
-
)
|
16
|
-
)
|
17
|
-
if filename is None:
|
18
|
-
filename = default_rel_path
|
19
|
-
|
20
|
-
# Try loading from source path first
|
21
|
-
abs_path = os.path.abspath(filename)
|
22
|
-
if os.path.exists(abs_path):
|
23
|
-
with open(abs_path, "r", encoding="utf-8") as f:
|
24
|
-
return f.read()
|
25
|
-
|
26
|
-
# If not found, try importlib.resources (for installed package)
|
27
|
-
try:
|
28
|
-
# Remove leading directories up to 'janito/agent/templates'
|
29
|
-
# and get the relative path inside the package
|
30
|
-
resource_path = filename
|
31
|
-
for marker in ["janito/agent/templates/", "agent/templates/"]:
|
32
|
-
idx = filename.replace("\\", "/").find(marker)
|
33
|
-
if idx != -1:
|
34
|
-
resource_path = filename[idx + len("janito/agent/templates/") :]
|
35
|
-
break
|
36
|
-
|
37
|
-
# Try loading from janito.agent.templates.profiles
|
38
|
-
if resource_path.startswith("profiles/"):
|
39
|
-
package = "janito.agent.templates.profiles"
|
40
|
-
resource = resource_path[len("profiles/") :]
|
41
|
-
elif resource_path.startswith("features/"):
|
42
|
-
package = "janito.agent.templates.features"
|
43
|
-
resource = resource_path[len("features/") :]
|
44
|
-
else:
|
45
|
-
package = "janito.agent.templates"
|
46
|
-
resource = resource_path
|
47
|
-
|
48
|
-
with (
|
49
|
-
importlib.resources.files(package)
|
50
|
-
.joinpath(resource)
|
51
|
-
.open("r", encoding="utf-8") as f
|
52
|
-
):
|
53
|
-
return f.read()
|
54
|
-
except Exception as e:
|
55
|
-
raise FileNotFoundError(
|
56
|
-
f"Prompt file not found at '{abs_path}' or in package resources: {e}"
|
57
|
-
)
|