janito 1.7.0__py3-none-any.whl → 1.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- janito/__init__.py +1 -1
- janito/agent/config.py +1 -1
- janito/agent/config_defaults.py +2 -2
- janito/agent/conversation.py +70 -27
- janito/agent/conversation_api.py +104 -4
- janito/agent/conversation_exceptions.py +6 -0
- janito/agent/conversation_tool_calls.py +17 -3
- janito/agent/event.py +24 -0
- janito/agent/event_dispatcher.py +24 -0
- janito/agent/event_handler_protocol.py +5 -0
- janito/agent/event_system.py +15 -0
- janito/agent/message_handler.py +4 -1
- janito/agent/message_handler_protocol.py +5 -0
- janito/agent/openai_client.py +5 -8
- janito/agent/openai_schema_generator.py +23 -4
- janito/agent/profile_manager.py +15 -83
- janito/agent/queued_message_handler.py +22 -3
- janito/agent/rich_message_handler.py +66 -72
- janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +14 -0
- janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +13 -0
- janito/agent/test_handler_protocols.py +47 -0
- janito/agent/tests/__init__.py +1 -0
- janito/agent/tool_base.py +1 -1
- janito/agent/tool_executor.py +109 -0
- janito/agent/tool_registry.py +3 -75
- janito/agent/tool_use_tracker.py +46 -0
- janito/agent/tools/__init__.py +8 -9
- janito/agent/tools/ask_user.py +19 -11
- janito/agent/tools/create_directory.py +43 -28
- janito/agent/tools/create_file.py +60 -29
- janito/agent/tools/dir_walk_utils.py +16 -0
- janito/agent/tools/fetch_url.py +10 -11
- janito/agent/tools/find_files.py +49 -32
- janito/agent/tools/get_lines.py +54 -18
- janito/agent/tools/memory.py +32 -52
- janito/agent/tools/move_file.py +72 -23
- janito/agent/tools/outline_file/__init__.py +85 -0
- janito/agent/tools/outline_file/formatting.py +20 -0
- janito/agent/tools/outline_file/markdown_outline.py +14 -0
- janito/agent/tools/outline_file/python_outline.py +71 -0
- janito/agent/tools/present_choices.py +62 -0
- janito/agent/tools/present_choices_test.py +18 -0
- janito/agent/tools/remove_directory.py +31 -26
- janito/agent/tools/remove_file.py +31 -13
- janito/agent/tools/replace_text_in_file.py +135 -36
- janito/agent/tools/run_bash_command.py +47 -50
- janito/agent/tools/run_powershell_command.py +52 -36
- janito/agent/tools/run_python_command.py +49 -29
- janito/agent/tools/search_outline.py +17 -0
- janito/agent/tools/search_text.py +208 -0
- janito/agent/tools/tools_utils.py +47 -4
- janito/agent/tools/utils.py +14 -15
- janito/agent/tools/validate_file_syntax.py +163 -0
- janito/cli/arg_parser.py +36 -4
- janito/cli/logging_setup.py +7 -2
- janito/cli/main.py +96 -2
- janito/cli/runner/_termweb_log_utils.py +17 -0
- janito/cli/runner/cli_main.py +119 -77
- janito/cli/runner/config.py +2 -2
- janito/cli/termweb_starter.py +73 -0
- janito/cli_chat_shell/chat_loop.py +42 -7
- janito/cli_chat_shell/chat_state.py +1 -1
- janito/cli_chat_shell/chat_ui.py +0 -1
- janito/cli_chat_shell/commands/__init__.py +15 -6
- janito/cli_chat_shell/commands/{history_reset.py → history_start.py} +13 -5
- janito/cli_chat_shell/commands/lang.py +16 -0
- janito/cli_chat_shell/commands/prompt.py +42 -0
- janito/cli_chat_shell/commands/session_control.py +36 -1
- janito/cli_chat_shell/commands/termweb_log.py +86 -0
- janito/cli_chat_shell/commands/utility.py +5 -2
- janito/cli_chat_shell/commands/verbose.py +29 -0
- janito/cli_chat_shell/session_manager.py +9 -1
- janito/cli_chat_shell/shell_command_completer.py +20 -0
- janito/cli_chat_shell/ui.py +110 -99
- janito/i18n/__init__.py +35 -0
- janito/i18n/messages.py +23 -0
- janito/i18n/pt.py +46 -0
- janito/rich_utils.py +43 -43
- janito/termweb/app.py +95 -0
- janito/termweb/static/editor.html +238 -0
- janito/termweb/static/editor.html.bak +238 -0
- janito/termweb/static/explorer.html.bak +59 -0
- janito/termweb/static/favicon.ico +0 -0
- janito/termweb/static/favicon.ico.bak +0 -0
- janito/termweb/static/index.html +55 -0
- janito/termweb/static/index.html.bak +55 -0
- janito/termweb/static/index.html.bak.bak +175 -0
- janito/termweb/static/landing.html.bak +36 -0
- janito/termweb/static/termicon.svg +1 -0
- janito/termweb/static/termweb.css +235 -0
- janito/termweb/static/termweb.css.bak +286 -0
- janito/termweb/static/termweb.js +187 -0
- janito/termweb/static/termweb.js.bak +187 -0
- janito/termweb/static/termweb.js.bak.bak +157 -0
- janito/termweb/static/termweb_quickopen.js +135 -0
- janito/termweb/static/termweb_quickopen.js.bak +125 -0
- janito/web/app.py +4 -4
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/METADATA +58 -25
- janito-1.8.0.dist-info/RECORD +127 -0
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/WHEEL +1 -1
- janito/agent/templates/profiles/system_prompt_template_base.toml +0 -76
- janito/agent/templates/profiles/system_prompt_template_default.toml +0 -3
- janito/agent/templates/profiles/system_prompt_template_technical.toml +0 -13
- janito/agent/tests/test_prompt_toml.py +0 -61
- janito/agent/tool_registry_core.py +0 -2
- janito/agent/tools/get_file_outline.py +0 -146
- janito/agent/tools/py_compile_file.py +0 -40
- janito/agent/tools/replace_file.py +0 -51
- janito/agent/tools/search_files.py +0 -65
- janito/cli/runner/scan.py +0 -57
- janito/cli_chat_shell/commands/system.py +0 -73
- janito-1.7.0.dist-info/RECORD +0 -89
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/entry_points.txt +0 -0
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/licenses/LICENSE +0 -0
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,35 @@
|
|
1
1
|
from janito.agent.rich_message_handler import RichMessageHandler
|
2
|
-
from .chat_state import load_chat_state
|
2
|
+
from .chat_state import load_chat_state, save_chat_state
|
3
3
|
from .chat_ui import setup_prompt_session, print_welcome_message
|
4
4
|
from .commands import handle_command
|
5
5
|
from janito.agent.conversation_exceptions import EmptyResponseError, ProviderError
|
6
6
|
|
7
|
+
# Track the active prompt session for cleanup
|
8
|
+
active_prompt_session = None
|
7
9
|
|
8
|
-
|
10
|
+
|
11
|
+
def start_chat_shell(
|
12
|
+
profile_manager,
|
13
|
+
continue_session=False,
|
14
|
+
max_rounds=50,
|
15
|
+
termweb_stdout_path=None,
|
16
|
+
termweb_stderr_path=None,
|
17
|
+
):
|
18
|
+
import janito.i18n as i18n
|
19
|
+
from janito.agent.runtime_config import runtime_config
|
20
|
+
|
21
|
+
i18n.set_locale(runtime_config.get("lang", "en"))
|
22
|
+
global active_prompt_session
|
9
23
|
agent = profile_manager.agent
|
10
24
|
message_handler = RichMessageHandler()
|
11
25
|
console = message_handler.console
|
12
26
|
|
13
27
|
# Load state
|
14
28
|
state = load_chat_state(continue_session)
|
29
|
+
if termweb_stdout_path:
|
30
|
+
state["termweb_stdout_path"] = termweb_stdout_path
|
31
|
+
if termweb_stderr_path:
|
32
|
+
state["termweb_stderr_path"] = termweb_stderr_path
|
15
33
|
messages = state["messages"]
|
16
34
|
mem_history = state["mem_history"]
|
17
35
|
last_usage_info_ref = {"value": state["last_usage_info"]}
|
@@ -22,7 +40,10 @@ def start_chat_shell(profile_manager, continue_session=False, max_rounds=50):
|
|
22
40
|
|
23
41
|
if (
|
24
42
|
profile_manager.system_prompt_template
|
25
|
-
and
|
43
|
+
and (
|
44
|
+
not runtime_config.get("vanilla_mode", False)
|
45
|
+
or runtime_config.get("system_prompt_template")
|
46
|
+
)
|
26
47
|
and not any(m.get("role") == "system" for m in messages)
|
27
48
|
):
|
28
49
|
messages.insert(0, {"role": "system", "content": agent.system_prompt_template})
|
@@ -32,10 +53,19 @@ def start_chat_shell(profile_manager, continue_session=False, max_rounds=50):
|
|
32
53
|
session = setup_prompt_session(
|
33
54
|
messages, last_usage_info_ref, last_elapsed, mem_history, profile_manager, agent
|
34
55
|
)
|
56
|
+
active_prompt_session = session
|
57
|
+
|
58
|
+
inject_message = state.get("inject_message")
|
59
|
+
if "inject_message" in state:
|
60
|
+
del state["inject_message"]
|
35
61
|
|
36
62
|
while True:
|
37
63
|
try:
|
38
|
-
if
|
64
|
+
if inject_message is not None:
|
65
|
+
user_input = inject_message
|
66
|
+
inject_message = None
|
67
|
+
was_paste_mode = False
|
68
|
+
elif state.get("paste_mode"):
|
39
69
|
console.print("")
|
40
70
|
user_input = session.prompt("Multiline> ", multiline=True)
|
41
71
|
was_paste_mode = True
|
@@ -44,7 +74,7 @@ def start_chat_shell(profile_manager, continue_session=False, max_rounds=50):
|
|
44
74
|
from prompt_toolkit.formatted_text import HTML
|
45
75
|
|
46
76
|
user_input = session.prompt(
|
47
|
-
HTML("<
|
77
|
+
HTML("<inputline>💬 </inputline>"), multiline=False
|
48
78
|
)
|
49
79
|
was_paste_mode = False
|
50
80
|
except EOFError:
|
@@ -55,7 +85,10 @@ def start_chat_shell(profile_manager, continue_session=False, max_rounds=50):
|
|
55
85
|
try:
|
56
86
|
confirm = (
|
57
87
|
session.prompt(
|
58
|
-
|
88
|
+
# Use <inputline> for full-line blue background, <prompt> for icon only
|
89
|
+
HTML(
|
90
|
+
"<inputline>Do you really want to exit? (y/n): </inputline>"
|
91
|
+
)
|
59
92
|
)
|
60
93
|
.strip()
|
61
94
|
.lower()
|
@@ -99,6 +132,8 @@ def start_chat_shell(profile_manager, continue_session=False, max_rounds=50):
|
|
99
132
|
|
100
133
|
start_time = time.time()
|
101
134
|
|
135
|
+
# No need to propagate verbose; ToolExecutor and others fetch from runtime_config
|
136
|
+
|
102
137
|
try:
|
103
138
|
response = profile_manager.agent.chat(
|
104
139
|
messages,
|
@@ -125,4 +160,4 @@ def start_chat_shell(profile_manager, continue_session=False, max_rounds=50):
|
|
125
160
|
last_usage_info_ref["value"] = usage
|
126
161
|
|
127
162
|
# Save conversation and input history
|
128
|
-
|
163
|
+
save_chat_state(messages, mem_history, last_usage_info_ref["value"])
|
@@ -9,7 +9,7 @@ from prompt_toolkit.history import InMemoryHistory
|
|
9
9
|
|
10
10
|
def load_chat_state(continue_session: bool):
|
11
11
|
messages = []
|
12
|
-
last_usage_info =
|
12
|
+
last_usage_info = {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0}
|
13
13
|
last_elapsed = None
|
14
14
|
history_list = load_input_history()
|
15
15
|
mem_history = InMemoryHistory()
|
janito/cli_chat_shell/chat_ui.py
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
from .session import handle_continue, handle_history
|
2
|
-
from .
|
2
|
+
from .prompt import handle_prompt, handle_role
|
3
3
|
from .session_control import handle_exit, handle_restart
|
4
4
|
from .utility import handle_help, handle_clear, handle_multi
|
5
|
+
from .termweb_log import handle_termweb_log_tail, handle_termweb_status
|
5
6
|
from .sum import handle_sum
|
6
7
|
from .config import handle_reload
|
7
|
-
from .
|
8
|
+
from .history_start import handle_start
|
8
9
|
from ..config_shell import handle_config_shell
|
10
|
+
from .verbose import handle_verbose
|
11
|
+
from .lang import handle_lang
|
9
12
|
from janito.agent.runtime_config import runtime_config
|
10
13
|
|
11
14
|
COMMAND_HANDLERS = {
|
15
|
+
"/termweb-logs": handle_termweb_log_tail,
|
16
|
+
"/termweb-status": handle_termweb_status,
|
12
17
|
"/history": handle_history,
|
13
18
|
"/continue": handle_continue,
|
14
19
|
"/exit": handle_exit,
|
@@ -16,20 +21,23 @@ COMMAND_HANDLERS = {
|
|
16
21
|
"/restart": handle_restart,
|
17
22
|
"/help": handle_help,
|
18
23
|
"/multi": handle_multi,
|
19
|
-
"/
|
24
|
+
"/prompt": handle_prompt,
|
25
|
+
"/verbose": handle_verbose,
|
20
26
|
}
|
21
27
|
|
22
28
|
if not runtime_config.get("vanilla_mode", False):
|
23
29
|
COMMAND_HANDLERS["/role"] = handle_role
|
24
30
|
|
31
|
+
|
32
|
+
COMMAND_HANDLERS["/lang"] = handle_lang
|
33
|
+
|
25
34
|
COMMAND_HANDLERS.update(
|
26
35
|
{
|
27
36
|
"/sum": handle_sum,
|
28
37
|
"/clear": handle_clear,
|
29
|
-
"/
|
38
|
+
"/start": handle_start,
|
30
39
|
"/config": handle_config_shell,
|
31
40
|
"/reload": handle_reload,
|
32
|
-
"/style": handle_style,
|
33
41
|
}
|
34
42
|
)
|
35
43
|
|
@@ -40,7 +48,8 @@ def handle_command(command, console, **kwargs):
|
|
40
48
|
args = parts[1:]
|
41
49
|
handler = COMMAND_HANDLERS.get(cmd)
|
42
50
|
if handler:
|
43
|
-
|
51
|
+
# Pass args as a keyword argument for handlers that expect it
|
52
|
+
return handler(console, args=args, **kwargs)
|
44
53
|
console.print(
|
45
54
|
f"[bold red]Invalid command: {cmd}. Type /help for a list of commands.[/bold red]"
|
46
55
|
)
|
@@ -2,14 +2,22 @@ from prompt_toolkit.history import InMemoryHistory
|
|
2
2
|
import os
|
3
3
|
|
4
4
|
|
5
|
-
def
|
5
|
+
def handle_start(console, state, **kwargs):
|
6
|
+
|
6
7
|
save_path = os.path.join(".janito", "last_conversation.json")
|
7
8
|
|
9
|
+
# Clear the terminal screen
|
10
|
+
os.system("cls" if os.name == "nt" else "clear")
|
11
|
+
|
8
12
|
# Clear in-memory conversation and prompt history
|
9
13
|
state["messages"].clear()
|
10
14
|
state["history_list"].clear()
|
11
15
|
state["mem_history"] = InMemoryHistory()
|
12
|
-
state["last_usage_info"] =
|
16
|
+
state["last_usage_info"] = {
|
17
|
+
"prompt_tokens": 0,
|
18
|
+
"completion_tokens": 0,
|
19
|
+
"total_tokens": 0,
|
20
|
+
}
|
13
21
|
state["last_elapsed"] = None
|
14
22
|
|
15
23
|
# Delete saved conversation file if exists
|
@@ -23,7 +31,7 @@ def handle_reset(console, state, **kwargs):
|
|
23
31
|
console.print(
|
24
32
|
f"[bold red]Failed to delete saved conversation:[/bold red] {e}"
|
25
33
|
)
|
26
|
-
else:
|
27
|
-
console.print("[bold yellow]No saved conversation to delete.[/bold yellow]")
|
28
34
|
|
29
|
-
console.print(
|
35
|
+
console.print(
|
36
|
+
"[bold green]Conversation history has been started (context reset).[/bold green]"
|
37
|
+
)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from janito.agent.runtime_config import runtime_config
|
2
|
+
import janito.i18n as i18n
|
3
|
+
|
4
|
+
|
5
|
+
def handle_lang(console, args=None, **kwargs):
|
6
|
+
if not args or len(args) == 0:
|
7
|
+
console.print(
|
8
|
+
"[bold yellow]Uso: /lang [código_idioma] (ex: pt, en, es)[/bold yellow]"
|
9
|
+
)
|
10
|
+
return
|
11
|
+
lang_code = args[0]
|
12
|
+
runtime_config.set("lang", lang_code)
|
13
|
+
i18n.set_locale(lang_code)
|
14
|
+
console.print(
|
15
|
+
f"[bold green]Idioma alterado para:[/bold green] [cyan]{lang_code}[/cyan]"
|
16
|
+
)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
from janito.agent.runtime_config import runtime_config
|
2
|
+
|
3
|
+
|
4
|
+
def handle_prompt(console, **kwargs):
|
5
|
+
profile_manager = kwargs.get("profile_manager")
|
6
|
+
prompt = profile_manager.system_prompt_template if profile_manager else None
|
7
|
+
if not prompt and profile_manager:
|
8
|
+
prompt = profile_manager.system_prompt_template
|
9
|
+
console.print(f"[bold magenta]System Prompt:[/bold magenta]\n{prompt}")
|
10
|
+
|
11
|
+
|
12
|
+
def handle_role(console, *args, **kwargs):
|
13
|
+
state = kwargs.get("state")
|
14
|
+
profile_manager = kwargs.get("profile_manager")
|
15
|
+
if not args:
|
16
|
+
console.print("[bold red]Usage: /role <new role description>[/bold red]")
|
17
|
+
return
|
18
|
+
new_role = " ".join(args)
|
19
|
+
if profile_manager:
|
20
|
+
profile_manager.set_role(new_role)
|
21
|
+
# Update system message in conversation
|
22
|
+
found = False
|
23
|
+
for msg in state["messages"]:
|
24
|
+
if msg.get("role") == "system":
|
25
|
+
msg["content"] = (
|
26
|
+
profile_manager.system_prompt_template if profile_manager else new_role
|
27
|
+
)
|
28
|
+
found = True
|
29
|
+
break
|
30
|
+
if not found:
|
31
|
+
state["messages"].insert(0, {"role": "system", "content": new_role})
|
32
|
+
# Also store the raw role string
|
33
|
+
if profile_manager:
|
34
|
+
setattr(profile_manager, "role_name", new_role)
|
35
|
+
runtime_config.set("role", new_role)
|
36
|
+
console.print(f"[bold green]System role updated to:[/bold green] {new_role}")
|
37
|
+
|
38
|
+
|
39
|
+
def handle_profile(console, *args, **kwargs):
|
40
|
+
"""/profile - Show the current and available Agent Profile (only 'base' is supported)"""
|
41
|
+
console.print("[bold green]Current profile:[/bold green] base")
|
42
|
+
console.print("[bold yellow]Available profiles:[/bold yellow]\n- base")
|
@@ -1,5 +1,40 @@
|
|
1
1
|
import os
|
2
2
|
import sys
|
3
|
+
import subprocess
|
4
|
+
|
5
|
+
|
6
|
+
def restart_cli():
|
7
|
+
# Clean up prompt_toolkit session if active
|
8
|
+
try:
|
9
|
+
from janito.cli_chat_shell import chat_loop
|
10
|
+
|
11
|
+
session = getattr(chat_loop, "active_prompt_session", None)
|
12
|
+
if session is not None and hasattr(session, "app"):
|
13
|
+
session.app.exit()
|
14
|
+
except Exception:
|
15
|
+
pass # Ignore cleanup errors
|
16
|
+
|
17
|
+
if os.name == "nt":
|
18
|
+
if (
|
19
|
+
"powershell" in os.environ.get("SHELL", "").lower()
|
20
|
+
or "pwsh" in sys.executable.lower()
|
21
|
+
):
|
22
|
+
args = [
|
23
|
+
"powershell",
|
24
|
+
"-Command",
|
25
|
+
"Start-Process",
|
26
|
+
sys.executable,
|
27
|
+
"-ArgumentList",
|
28
|
+
"'-m','janito"
|
29
|
+
+ ("','" + "','".join(sys.argv[1:]) if sys.argv[1:] else "")
|
30
|
+
+ "'",
|
31
|
+
]
|
32
|
+
subprocess.Popen(args)
|
33
|
+
else:
|
34
|
+
subprocess.Popen([sys.executable, "-m", "janito"] + sys.argv[1:])
|
35
|
+
sys.exit(0)
|
36
|
+
else:
|
37
|
+
os.execv(sys.executable, [sys.executable, "-m", "janito"] + sys.argv[1:])
|
3
38
|
|
4
39
|
|
5
40
|
def handle_exit(console, **kwargs):
|
@@ -9,4 +44,4 @@ def handle_exit(console, **kwargs):
|
|
9
44
|
|
10
45
|
def handle_restart(console, **kwargs):
|
11
46
|
console.print("[bold yellow]Restarting CLI...[/bold yellow]")
|
12
|
-
|
47
|
+
restart_cli()
|
@@ -0,0 +1,86 @@
|
|
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, state=None, **kwargs):
|
18
|
+
lines = 20
|
19
|
+
if args and args[0].isdigit():
|
20
|
+
lines = int(args[0])
|
21
|
+
stdout_path = state.get("termweb_stdout_path") if state else None
|
22
|
+
stderr_path = state.get("termweb_stderr_path") if 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
|
+
def handle_termweb_status(console: Console, *args, state=None, **kwargs):
|
55
|
+
if state is None:
|
56
|
+
console.print(
|
57
|
+
"[red]No shell state available. Cannot determine termweb status.[/red]"
|
58
|
+
)
|
59
|
+
return
|
60
|
+
port = state.get("termweb_port")
|
61
|
+
port_source = "state"
|
62
|
+
if not port:
|
63
|
+
port = runtime_config.get("termweb_port")
|
64
|
+
port_source = "runtime_config"
|
65
|
+
pid = state.get("termweb_pid")
|
66
|
+
stdout_path = state.get("termweb_stdout_path")
|
67
|
+
stderr_path = state.get("termweb_stderr_path")
|
68
|
+
running = False
|
69
|
+
if port:
|
70
|
+
running = is_termweb_running(port)
|
71
|
+
console.print("[bold cyan]TermWeb Server Status:[/bold cyan]")
|
72
|
+
console.print(f" Running: {'[green]Yes[/green]' if running else '[red]No[/red]'}")
|
73
|
+
if pid:
|
74
|
+
console.print(f" PID: {pid}")
|
75
|
+
if port:
|
76
|
+
console.print(f" Port: {port} (from {port_source})")
|
77
|
+
url = f"http://localhost:{port}/"
|
78
|
+
console.print(f" URL: [underline blue]{url}[/underline blue]")
|
79
|
+
else:
|
80
|
+
console.print(
|
81
|
+
" [yellow]No port configured in state or runtime_config.[/yellow]"
|
82
|
+
)
|
83
|
+
if stdout_path:
|
84
|
+
console.print(f" Stdout log: {stdout_path}")
|
85
|
+
if stderr_path:
|
86
|
+
console.print(f" Stderr log: {stderr_path}")
|
@@ -6,12 +6,15 @@ def handle_help(console, **kwargs):
|
|
6
6
|
/restart - Restart the CLI
|
7
7
|
/help - Show this help message
|
8
8
|
/continue - Restore last saved conversation
|
9
|
-
/
|
10
|
-
/
|
9
|
+
/start - Reset conversation history
|
10
|
+
/prompt - Show the system prompt
|
11
11
|
/role - Change the system role
|
12
12
|
/clear - Clear the terminal screen
|
13
13
|
/multi - Provide multiline input as next message
|
14
14
|
/config - Show or set configuration (see: /config show, /config set local|global key=value)
|
15
|
+
/termweb-logs - Show the last lines of the latest termweb logs
|
16
|
+
/termweb-status - Show status information about the running termweb server
|
17
|
+
/verbose [on|off] - Show or set verbose mode for this session
|
15
18
|
"""
|
16
19
|
)
|
17
20
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from janito.agent.runtime_config import runtime_config
|
2
|
+
|
3
|
+
|
4
|
+
def handle_verbose(console, state, **kwargs):
|
5
|
+
"""
|
6
|
+
/verbose [on|off]
|
7
|
+
Shows or sets verbose mode for the current shell session.
|
8
|
+
"""
|
9
|
+
args = kwargs.get("args", [])
|
10
|
+
verbose = runtime_config.get("verbose", False)
|
11
|
+
if not args:
|
12
|
+
status = "ON" if verbose else "OFF"
|
13
|
+
console.print(
|
14
|
+
f"[bold green]/verbose:[/bold green] Verbose mode is currently [bold]{status}[/bold]."
|
15
|
+
)
|
16
|
+
return
|
17
|
+
arg = args[0].lower()
|
18
|
+
if arg == "on":
|
19
|
+
runtime_config["verbose"] = True
|
20
|
+
console.print(
|
21
|
+
"[bold green]/verbose:[/bold green] Verbose mode is now [bold]ON[/bold]."
|
22
|
+
)
|
23
|
+
elif arg == "off":
|
24
|
+
runtime_config["verbose"] = False
|
25
|
+
console.print(
|
26
|
+
"[bold green]/verbose:[/bold green] Verbose mode is now [bold]OFF[/bold]."
|
27
|
+
)
|
28
|
+
else:
|
29
|
+
console.print("[bold red]Usage:[/bold red] /verbose [on|off]")
|
@@ -27,8 +27,16 @@ def save_conversation(
|
|
27
27
|
):
|
28
28
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
29
29
|
data = {"messages": messages, "prompts": prompts, "last_usage_info": usage_info}
|
30
|
+
|
31
|
+
def usage_serializer(obj):
|
32
|
+
if hasattr(obj, "to_dict"):
|
33
|
+
return obj.to_dict()
|
34
|
+
if hasattr(obj, "__dict__"):
|
35
|
+
return obj.__dict__
|
36
|
+
return str(obj)
|
37
|
+
|
30
38
|
with open(path, "w", encoding="utf-8") as f:
|
31
|
-
json.dump(data, f, indent=2)
|
39
|
+
json.dump(data, f, indent=2, default=usage_serializer)
|
32
40
|
|
33
41
|
|
34
42
|
def load_input_history():
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from prompt_toolkit.completion import Completer, Completion
|
2
|
+
|
3
|
+
|
4
|
+
class ShellCommandCompleter(Completer):
|
5
|
+
def __init__(self):
|
6
|
+
# Import here to avoid circular import at module level
|
7
|
+
from janito.cli_chat_shell.commands import COMMAND_HANDLERS
|
8
|
+
|
9
|
+
# Only commands starting with '/'
|
10
|
+
self.commands = sorted(
|
11
|
+
[cmd for cmd in COMMAND_HANDLERS.keys() if cmd.startswith("/")]
|
12
|
+
)
|
13
|
+
|
14
|
+
def get_completions(self, document, complete_event):
|
15
|
+
text = document.text_before_cursor
|
16
|
+
if text.startswith("/"):
|
17
|
+
prefix = text[1:]
|
18
|
+
for cmd in self.commands:
|
19
|
+
if cmd[1:].startswith(prefix):
|
20
|
+
yield Completion(cmd, start_position=-(len(prefix) + 1))
|