janito 2.4.0__py3-none-any.whl → 2.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- janito/agent/setup_agent.py +4 -3
- janito/agent/templates/profiles/system_prompt_template_assistant.txt.j2 +1 -0
- janito/cli/chat_mode/script_runner.py +153 -0
- janito/cli/chat_mode/session.py +56 -36
- janito/cli/chat_mode/session_profile_select.py +1 -1
- janito/cli/chat_mode/shell/commands/__init__.py +6 -2
- janito/cli/chat_mode/shell/commands/bang.py +36 -0
- janito/cli/chat_mode/shell/commands/conversation_restart.py +4 -28
- janito/cli/chat_mode/shell/commands/execute.py +1 -2
- janito/cli/chat_mode/shell/commands/help.py +1 -1
- janito/cli/chat_mode/shell/commands/prompt.py +1 -16
- janito/cli/chat_mode/shell/commands/read.py +1 -2
- janito/cli/chat_mode/shell/commands/role.py +2 -9
- janito/cli/chat_mode/shell/commands/write.py +1 -2
- janito/cli/chat_mode/shell/input_history.py +1 -1
- janito/cli/chat_mode/shell/session/manager.py +0 -68
- janito/cli/core/runner.py +4 -4
- janito/cli/main_cli.py +12 -5
- janito/cli/prompt_setup.py +2 -2
- janito/cli/rich_terminal_reporter.py +21 -6
- janito/cli/single_shot_mode/handler.py +13 -7
- janito/drivers/driver_registry.py +0 -2
- janito/formatting_token.py +7 -6
- janito/llm/agent.py +1 -1
- janito/provider_registry.py +1 -1
- janito/providers/__init__.py +0 -2
- janito/providers/provider_static_info.py +0 -3
- janito/tools/adapters/local/validate_file_syntax/core.py +1 -1
- janito/tools/tool_base.py +0 -10
- {janito-2.4.0.dist-info → janito-2.5.1.dist-info}/METADATA +2 -15
- {janito-2.4.0.dist-info → janito-2.5.1.dist-info}/RECORD +35 -32
- {janito-2.4.0.dist-info → janito-2.5.1.dist-info}/WHEEL +0 -0
- {janito-2.4.0.dist-info → janito-2.5.1.dist-info}/entry_points.txt +0 -0
- {janito-2.4.0.dist-info → janito-2.5.1.dist-info}/licenses/LICENSE +0 -0
- {janito-2.4.0.dist-info → janito-2.5.1.dist-info}/top_level.txt +0 -0
janito/agent/setup_agent.py
CHANGED
@@ -20,7 +20,7 @@ def setup_agent(
|
|
20
20
|
output_queue=None,
|
21
21
|
verbose_tools=False,
|
22
22
|
verbose_agent=False,
|
23
|
-
|
23
|
+
|
24
24
|
allowed_permissions=None,
|
25
25
|
profile=None,
|
26
26
|
profile_system_prompt=None,
|
@@ -156,6 +156,7 @@ def setup_agent(
|
|
156
156
|
agent.template_vars["profile"] = profile
|
157
157
|
# Store template path and context for dynamic prompt refresh
|
158
158
|
agent.system_prompt_template = str(template_path)
|
159
|
+
|
159
160
|
agent._template_vars = context.copy()
|
160
161
|
agent._original_template_vars = context.copy()
|
161
162
|
return agent
|
@@ -170,7 +171,7 @@ def create_configured_agent(
|
|
170
171
|
verbose_agent=False,
|
171
172
|
templates_dir=None,
|
172
173
|
zero_mode=False,
|
173
|
-
|
174
|
+
|
174
175
|
allowed_permissions=None,
|
175
176
|
profile=None,
|
176
177
|
profile_system_prompt=None,
|
@@ -212,7 +213,7 @@ def create_configured_agent(
|
|
212
213
|
output_queue=output_queue,
|
213
214
|
verbose_tools=verbose_tools,
|
214
215
|
verbose_agent=verbose_agent,
|
215
|
-
|
216
|
+
|
216
217
|
allowed_permissions=allowed_permissions,
|
217
218
|
profile=profile,
|
218
219
|
profile_system_prompt=profile_system_prompt,
|
@@ -0,0 +1 @@
|
|
1
|
+
You are a helpful assistant.
|
@@ -0,0 +1,153 @@
|
|
1
|
+
"""
|
2
|
+
Scripted runner for Janito chat mode.
|
3
|
+
|
4
|
+
This utility allows you to execute the interactive ``ChatSession`` logic with
|
5
|
+
an *in-memory* list of user inputs, making it much easier to write automated
|
6
|
+
unit or integration tests for the chat CLI without resorting to fragile
|
7
|
+
pseudo-terminal tricks.
|
8
|
+
|
9
|
+
The runner monkey-patches the private ``_handle_input`` method so that the
|
10
|
+
chat loop thinks it is receiving interactive input, while in reality the
|
11
|
+
values come from the provided list. All output is captured through a
|
12
|
+
``rich.console.Console`` instance configured with ``record=True`` so the test
|
13
|
+
can later inspect the rendered text.
|
14
|
+
|
15
|
+
Typical usage
|
16
|
+
-------------
|
17
|
+
>>> from janito.cli.chat_mode.script_runner import ChatScriptRunner
|
18
|
+
>>> inputs = ["Hello!", "/exit"]
|
19
|
+
>>> runner = ChatScriptRunner(inputs)
|
20
|
+
>>> transcript = runner.run()
|
21
|
+
>>> assert "Hello!" in transcript
|
22
|
+
|
23
|
+
The ``ChatScriptRunner`` purposefully replaces the internal call to the agent
|
24
|
+
with a real agent call by default. If you want to use a stub, you must modify the runner implementation.
|
25
|
+
"""
|
26
|
+
from __future__ import annotations
|
27
|
+
|
28
|
+
from types import MethodType
|
29
|
+
from typing import List, Optional
|
30
|
+
|
31
|
+
from rich.console import Console
|
32
|
+
|
33
|
+
from janito.cli.chat_mode.session import ChatSession
|
34
|
+
from janito.provider_registry import ProviderRegistry
|
35
|
+
from janito.llm.driver_config import LLMDriverConfig
|
36
|
+
|
37
|
+
__all__ = ["ChatScriptRunner"]
|
38
|
+
|
39
|
+
|
40
|
+
auth_warning = (
|
41
|
+
"[yellow]ChatScriptRunner is executing in stubbed-agent mode; no calls to an "
|
42
|
+
"external LLM provider will be made.[/yellow]"
|
43
|
+
)
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
class ChatScriptRunner:
|
48
|
+
"""Run a **ChatSession** non-interactively using a predefined set of inputs."""
|
49
|
+
|
50
|
+
def __init__(
|
51
|
+
self,
|
52
|
+
inputs: List[str],
|
53
|
+
*,
|
54
|
+
console: Optional[Console] = None,
|
55
|
+
provider: str = "openai",
|
56
|
+
model: str = "gpt-4.1",
|
57
|
+
use_real_agent: bool = True,
|
58
|
+
**chat_session_kwargs,
|
59
|
+
) -> None:
|
60
|
+
"""Create the runner.
|
61
|
+
|
62
|
+
Parameters
|
63
|
+
----------
|
64
|
+
inputs:
|
65
|
+
Ordered list of strings that will be fed to the chat loop.
|
66
|
+
console:
|
67
|
+
Optional *rich* console. If *None*, a new one is created with
|
68
|
+
*record=True* so that output can later be retrieved through
|
69
|
+
:py:meth:`rich.console.Console.export_text`.
|
70
|
+
use_real_agent:
|
71
|
+
chat_session_kwargs:
|
72
|
+
Extra keyword arguments forwarded to :class:`janito.cli.chat_mode.session.ChatSession`.
|
73
|
+
"""
|
74
|
+
self._input_queue = list(inputs)
|
75
|
+
self.console = console or Console(record=True)
|
76
|
+
self.provider = provider
|
77
|
+
self.model = model
|
78
|
+
self.use_real_agent = use_real_agent
|
79
|
+
# Ensure we always pass a non-interactive *args* namespace so that the
|
80
|
+
# normal ChatSession logic skips the Questionary profile prompt which
|
81
|
+
# is incompatible with headless test runs.
|
82
|
+
if "args" not in chat_session_kwargs or chat_session_kwargs["args"] is None:
|
83
|
+
from types import SimpleNamespace
|
84
|
+
chat_session_kwargs["args"] = SimpleNamespace(
|
85
|
+
profile="developer",
|
86
|
+
provider=self.provider,
|
87
|
+
model=self.model,
|
88
|
+
)
|
89
|
+
|
90
|
+
# Create the ChatSession instance **after** we monkey-patch methods that rely on
|
91
|
+
# prompt-toolkit so that no attempt is made to instantiate terminal UIs in
|
92
|
+
# a headless environment like CI.
|
93
|
+
|
94
|
+
# 1) Patch *ChatSession._create_prompt_session* to do nothing – the
|
95
|
+
# interactive session object is irrelevant for scripted runs.
|
96
|
+
from types import MethodType as _MT
|
97
|
+
if "_original_create_prompt_session" not in ChatSession.__dict__:
|
98
|
+
ChatSession._original_create_prompt_session = ChatSession._create_prompt_session # type: ignore[attr-defined]
|
99
|
+
ChatSession._create_prompt_session = _MT(lambda _self: None, ChatSession) # type: ignore[method-assign]
|
100
|
+
|
101
|
+
# Resolve provider instance now so that ChatSession uses a ready agent
|
102
|
+
provider_instance = ProviderRegistry().get_instance(self.provider)
|
103
|
+
if provider_instance is None:
|
104
|
+
raise RuntimeError(f"Provider '{self.provider}' is not available on this system.")
|
105
|
+
driver_config = LLMDriverConfig(model=self.model)
|
106
|
+
chat_session_kwargs.setdefault("provider_instance", provider_instance)
|
107
|
+
chat_session_kwargs.setdefault("llm_driver_config", driver_config)
|
108
|
+
|
109
|
+
self.chat_session = ChatSession(console=self.console, **chat_session_kwargs)
|
110
|
+
|
111
|
+
|
112
|
+
# Monkey-patch the *ChatSession._handle_input* method so that it pops
|
113
|
+
# from our in-memory queue instead of reading from stdin.
|
114
|
+
def _script_handle_input(this: ChatSession, _prompt_session_unused): # noqa: D401
|
115
|
+
if not self._input_queue:
|
116
|
+
# Signal normal shutdown
|
117
|
+
this._handle_exit()
|
118
|
+
return None
|
119
|
+
return self._input_queue.pop(0)
|
120
|
+
|
121
|
+
# Bind the method to the *chat_session* instance.
|
122
|
+
self.chat_session._handle_input = MethodType( # type: ignore[assignment]
|
123
|
+
_script_handle_input, self.chat_session
|
124
|
+
)
|
125
|
+
|
126
|
+
# ---------------------------------------------------------------------
|
127
|
+
# Public helpers
|
128
|
+
# ---------------------------------------------------------------------
|
129
|
+
def run(self) -> str:
|
130
|
+
"""Execute the chat session and return the captured transcript."""
|
131
|
+
self.chat_session.run()
|
132
|
+
return self.console.export_text()
|
133
|
+
|
134
|
+
# ---------------------------------------------------------------------
|
135
|
+
# Helpers to introspect results
|
136
|
+
# ---------------------------------------------------------------------
|
137
|
+
def get_history(self):
|
138
|
+
"""Return the structured conversation history produced by the LLM."""
|
139
|
+
try:
|
140
|
+
return self.chat_session.shell_state.conversation_history.get_history()
|
141
|
+
except Exception:
|
142
|
+
return []
|
143
|
+
|
144
|
+
def get_last_response(self) -> str | None:
|
145
|
+
"""Return the *assistant* content of the last message, if any."""
|
146
|
+
history = self.get_history()
|
147
|
+
for message in reversed(history):
|
148
|
+
if message.get("role") == "assistant":
|
149
|
+
return message.get("content")
|
150
|
+
return None
|
151
|
+
|
152
|
+
# Convenience alias so tests can simply call *runner()*
|
153
|
+
__call__ = run
|
janito/cli/chat_mode/session.py
CHANGED
@@ -54,7 +54,7 @@ class ChatSession:
|
|
54
54
|
args=None,
|
55
55
|
verbose_tools=False,
|
56
56
|
verbose_agent=False,
|
57
|
-
|
57
|
+
|
58
58
|
allowed_permissions=None,
|
59
59
|
):
|
60
60
|
|
@@ -76,12 +76,9 @@ class ChatSession:
|
|
76
76
|
from janito.cli.chat_mode.session_profile_select import select_profile
|
77
77
|
|
78
78
|
result = select_profile()
|
79
|
-
if (
|
80
|
-
|
81
|
-
|
82
|
-
and result.get("profile_system_prompt")
|
83
|
-
):
|
84
|
-
profile_system_prompt = result["profile_system_prompt"]
|
79
|
+
if isinstance(result, dict):
|
80
|
+
profile = result.get("profile")
|
81
|
+
profile_system_prompt = result.get("profile_system_prompt")
|
85
82
|
elif isinstance(result, str) and result.startswith("role:"):
|
86
83
|
role = result[len("role:") :].strip()
|
87
84
|
profile = "developer"
|
@@ -105,7 +102,7 @@ class ChatSession:
|
|
105
102
|
role=role,
|
106
103
|
verbose_tools=verbose_tools,
|
107
104
|
verbose_agent=verbose_agent,
|
108
|
-
|
105
|
+
|
109
106
|
allowed_permissions=allowed_permissions,
|
110
107
|
profile=profile,
|
111
108
|
profile_system_prompt=profile_system_prompt,
|
@@ -163,6 +160,14 @@ class ChatSession:
|
|
163
160
|
f"[bold green]Janito Chat Mode v{__version__}[/bold green]"
|
164
161
|
)
|
165
162
|
self.console.print("[green]/help for commands /exit or Ctrl+C to quit[/green]")
|
163
|
+
import os
|
164
|
+
cwd = os.getcwd()
|
165
|
+
home = os.path.expanduser('~')
|
166
|
+
if cwd.startswith(home):
|
167
|
+
cwd_display = '~' + cwd[len(home):]
|
168
|
+
else:
|
169
|
+
cwd_display = cwd
|
170
|
+
self.console.print(f"[green]Working Dir:[/green] {cwd_display}")
|
166
171
|
|
167
172
|
# Inform user if no privileges are enabled
|
168
173
|
from janito.cli.chat_mode.shell.commands._priv_check import user_has_any_privileges
|
@@ -185,40 +190,55 @@ class ChatSession:
|
|
185
190
|
continue
|
186
191
|
if self._handle_exit_conditions(cmd_input):
|
187
192
|
break
|
188
|
-
if
|
189
|
-
handle_command(cmd_input, shell_state=self.shell_state)
|
193
|
+
if self._handle_command_input(cmd_input):
|
190
194
|
continue
|
191
195
|
self.user_input_history.append(cmd_input)
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
+
self._process_prompt(cmd_input)
|
197
|
+
|
198
|
+
def _handle_command_input(self, cmd_input):
|
199
|
+
if cmd_input.startswith("/"):
|
200
|
+
handle_command(cmd_input, shell_state=self.shell_state)
|
201
|
+
return True
|
202
|
+
if cmd_input.startswith("!"):
|
203
|
+
# Pass everything after ! to the bang handler
|
204
|
+
handle_command(f"! {cmd_input[1:]}", shell_state=self.shell_state)
|
205
|
+
return True
|
206
|
+
return False
|
207
|
+
|
208
|
+
def _process_prompt(self, cmd_input):
|
209
|
+
try:
|
210
|
+
import time
|
211
|
+
final_event = (
|
212
|
+
self._prompt_handler.agent.last_event
|
213
|
+
if hasattr(self._prompt_handler.agent, "last_event")
|
214
|
+
else None
|
215
|
+
)
|
216
|
+
start_time = time.time()
|
217
|
+
self._prompt_handler.run_prompt(cmd_input)
|
218
|
+
end_time = time.time()
|
219
|
+
elapsed = end_time - start_time
|
220
|
+
self.msg_count += 1
|
221
|
+
# After prompt, print the stat line using the shared core function
|
222
|
+
from janito.formatting_token import print_token_message_summary
|
223
|
+
|
224
|
+
usage = self.performance_collector.get_last_request_usage()
|
225
|
+
print_token_message_summary(self.console, self.msg_count, usage, elapsed=elapsed)
|
226
|
+
# Print exit reason if present in the final event
|
227
|
+
if final_event and hasattr(final_event, "metadata"):
|
228
|
+
exit_reason = (
|
229
|
+
final_event.metadata.get("exit_reason")
|
230
|
+
if hasattr(final_event, "metadata")
|
196
231
|
else None
|
197
232
|
)
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
from janito.formatting_token import print_token_message_summary
|
202
|
-
|
203
|
-
usage = self.performance_collector.get_last_request_usage()
|
204
|
-
print_token_message_summary(self.console, self.msg_count, usage)
|
205
|
-
# Print exit reason if present in the final event
|
206
|
-
if final_event and hasattr(final_event, "metadata"):
|
207
|
-
exit_reason = (
|
208
|
-
final_event.metadata.get("exit_reason")
|
209
|
-
if hasattr(final_event, "metadata")
|
210
|
-
else None
|
233
|
+
if exit_reason:
|
234
|
+
self.console.print(
|
235
|
+
f"[bold yellow]Exit reason: {exit_reason}[/bold yellow]"
|
211
236
|
)
|
212
|
-
if exit_reason:
|
213
|
-
self.console.print(
|
214
|
-
f"[bold yellow]Exit reason: {exit_reason}[/bold yellow]"
|
215
|
-
)
|
216
|
-
|
217
|
-
except Exception as exc:
|
218
|
-
self.console.print(f"[red]Exception in agent: {exc}[/red]")
|
219
|
-
import traceback
|
220
237
|
|
221
|
-
|
238
|
+
except Exception as exc:
|
239
|
+
self.console.print(f"[red]Exception in agent: {exc}[/red]")
|
240
|
+
import traceback
|
241
|
+
self.console.print(traceback.format_exc())
|
222
242
|
|
223
243
|
def _create_prompt_session(self):
|
224
244
|
return PromptSession(
|
@@ -22,7 +22,7 @@ def select_profile():
|
|
22
22
|
style=custom_style
|
23
23
|
).ask()
|
24
24
|
if answer == "helpful assistant":
|
25
|
-
return {"profile":
|
25
|
+
return {"profile": "assistant", "profile_system_prompt": None}
|
26
26
|
if answer == "using role...":
|
27
27
|
role_name = questionary.text("Enter the role name:").ask()
|
28
28
|
return f"role:{role_name}"
|
@@ -2,7 +2,7 @@ from .base import ShellCmdHandler
|
|
2
2
|
from .history_view import ViewShellHandler
|
3
3
|
from .lang import LangShellHandler
|
4
4
|
from .livelogs import LivelogsShellHandler
|
5
|
-
from .prompt import PromptShellHandler, RoleShellHandler
|
5
|
+
from .prompt import PromptShellHandler, RoleShellHandler
|
6
6
|
from .multi import MultiShellHandler
|
7
7
|
from .model import ModelShellHandler
|
8
8
|
from .role import RoleCommandShellHandler
|
@@ -12,6 +12,10 @@ from .help import HelpShellHandler
|
|
12
12
|
from janito.cli.console import shared_console
|
13
13
|
|
14
14
|
COMMAND_HANDLERS = {
|
15
|
+
# Bang handler for shell commands
|
16
|
+
"!": __import__(
|
17
|
+
"janito.cli.chat_mode.shell.commands.bang", fromlist=["BangShellHandler"]
|
18
|
+
).BangShellHandler,
|
15
19
|
"/execute": __import__(
|
16
20
|
"janito.cli.chat_mode.shell.commands.execute", fromlist=["ExecuteShellHandler"]
|
17
21
|
).ExecuteShellHandler,
|
@@ -34,7 +38,7 @@ COMMAND_HANDLERS = {
|
|
34
38
|
"/livelogs": LivelogsShellHandler,
|
35
39
|
"/prompt": PromptShellHandler,
|
36
40
|
"/role": RoleShellHandler,
|
37
|
-
|
41
|
+
|
38
42
|
"/history": HistoryShellHandler,
|
39
43
|
|
40
44
|
"/tools": ToolsShellHandler,
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
from janito.platform_discovery import PlatformDiscovery
|
4
|
+
import subprocess
|
5
|
+
import sys
|
6
|
+
|
7
|
+
class BangShellHandler(ShellCmdHandler):
|
8
|
+
help_text = "!<cmd>: Run a shell command in the underlying shell (PowerShell or Bash). Usage: !ls -al or !Get-Process. Use ! with no command to launch an interactive shell."
|
9
|
+
|
10
|
+
def run(self):
|
11
|
+
if not self.shell_state:
|
12
|
+
shared_console.print("[red]Shell state unavailable.[/red]")
|
13
|
+
return
|
14
|
+
cmd = (self.after_cmd_line or "").strip()
|
15
|
+
if not cmd:
|
16
|
+
pd = PlatformDiscovery()
|
17
|
+
if pd.is_windows():
|
18
|
+
shared_console.print("[yellow]Launching interactive PowerShell. Type 'exit' to return.[/yellow]")
|
19
|
+
subprocess.run(["powershell.exe"], check=False)
|
20
|
+
else:
|
21
|
+
shared_console.print("[yellow]Launching interactive Bash shell. Type 'exit' to return.[/yellow]")
|
22
|
+
subprocess.run(["bash"], check=False)
|
23
|
+
return
|
24
|
+
pd = PlatformDiscovery()
|
25
|
+
if pd.is_windows():
|
26
|
+
shared_console.print(f"[cyan]Running in PowerShell:[/cyan] {cmd}")
|
27
|
+
completed = subprocess.run(["powershell.exe", "-Command", cmd], capture_output=True, text=True)
|
28
|
+
else:
|
29
|
+
shared_console.print(f"[cyan]Running in Bash:[/cyan] {cmd}")
|
30
|
+
completed = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
31
|
+
output = completed.stdout
|
32
|
+
error = completed.stderr
|
33
|
+
if output:
|
34
|
+
shared_console.print(output)
|
35
|
+
if error:
|
36
|
+
shared_console.print(f"[red]{error}[/red]")
|
@@ -5,31 +5,8 @@ from janito.cli.console import shared_console
|
|
5
5
|
|
6
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
|
-
)
|
12
|
-
|
13
8
|
reset_session_id()
|
14
|
-
|
15
|
-
|
16
|
-
# --- Append end-of-conversation message to old history if it exists and is non-trivial ---
|
17
|
-
if os.path.exists(save_path):
|
18
|
-
try:
|
19
|
-
messages, prompts, usage = load_last_conversation(save_path)
|
20
|
-
if messages and (
|
21
|
-
len(messages) > 1
|
22
|
-
or (len(messages) == 1 and messages[0].get("role") != "system")
|
23
|
-
):
|
24
|
-
messages.append(
|
25
|
-
{"role": "system", "content": "[Session ended by user]"}
|
26
|
-
)
|
27
|
-
# Save to permanent chat history (let save_conversation pick session file)
|
28
|
-
save_conversation(messages, prompts, usage)
|
29
|
-
except Exception as e:
|
30
|
-
shared_console.print(
|
31
|
-
f"[bold red]Failed to update previous conversation history:[/bold red] {e}"
|
32
|
-
)
|
9
|
+
# Conversation history is no longer saved or loaded.
|
33
10
|
|
34
11
|
# Clear the terminal screen
|
35
12
|
shared_console.clear()
|
@@ -40,8 +17,7 @@ def handle_restart(shell_state=None):
|
|
40
17
|
# Reset system prompt to original template context if available
|
41
18
|
if hasattr(shell_state.agent, "_original_template_vars"):
|
42
19
|
shell_state.agent._template_vars = shell_state.agent._original_template_vars.copy()
|
43
|
-
|
44
|
-
shell_state.agent._refresh_system_prompt_from_template()
|
20
|
+
shell_state.agent.refresh_system_prompt_from_template()
|
45
21
|
# No need to print the system prompt after restart
|
46
22
|
|
47
23
|
# Reset tool use tracker
|
@@ -85,8 +61,8 @@ def handle_restart(shell_state=None):
|
|
85
61
|
janito.tools.local_tools_adapter.set_allowed_permissions(ToolPermissions(read=False, write=False, execute=False))
|
86
62
|
msg = "[green]All tool permissions have been set to OFF (read, write, execute = False).[/green]"
|
87
63
|
# Refresh system prompt to reflect new permissions
|
88
|
-
if hasattr(shell_state, "agent") and shell_state.agent and hasattr(shell_state.agent, "
|
89
|
-
shell_state.agent.
|
64
|
+
if hasattr(shell_state, "agent") and shell_state.agent and hasattr(shell_state.agent, "refresh_system_prompt_from_template"):
|
65
|
+
shell_state.agent.refresh_system_prompt_from_template()
|
90
66
|
if msg:
|
91
67
|
shared_console.print(msg)
|
92
68
|
|
@@ -33,8 +33,7 @@ class ExecuteShellHandler(ShellCmdHandler):
|
|
33
33
|
# Refresh system prompt if agent is available
|
34
34
|
agent = getattr(self.shell_state, "agent", None)
|
35
35
|
if agent:
|
36
|
-
|
37
|
-
agent._refresh_system_prompt_from_template()
|
36
|
+
agent.refresh_system_prompt_from_template()
|
38
37
|
# No need to print the system prompt after permission change
|
39
38
|
if enable:
|
40
39
|
shared_console.print("[green]Execution tools ENABLED. Tools can now execute code and commands.[/green]")
|
@@ -41,24 +41,9 @@ class RoleShellHandler(ShellCmdHandler):
|
|
41
41
|
if agent and hasattr(agent, "set_template_var"):
|
42
42
|
agent.set_template_var("role", new_role)
|
43
43
|
# Refresh the system prompt with the new role if possible
|
44
|
-
|
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
|
-
)
|
44
|
+
agent.refresh_system_prompt_from_template()
|
52
45
|
shared_console.print(
|
53
46
|
f"[bold green]System role updated to:[/bold green] {new_role}"
|
54
47
|
)
|
55
48
|
|
56
49
|
|
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")
|
@@ -28,8 +28,7 @@ class ReadShellHandler(ShellCmdHandler):
|
|
28
28
|
# Refresh system prompt if agent is available
|
29
29
|
agent = getattr(self.shell_state, "agent", None)
|
30
30
|
if agent:
|
31
|
-
|
32
|
-
agent._refresh_system_prompt_from_template()
|
31
|
+
agent.refresh_system_prompt_from_template()
|
33
32
|
# No need to print the system prompt after permission change
|
34
33
|
if enable:
|
35
34
|
shared_console.print("[green]Read permissions ENABLED. Tools can now read files and data.[/green]")
|
@@ -20,15 +20,8 @@ class RoleCommandShellHandler(ShellCmdHandler):
|
|
20
20
|
new_role = " ".join(args)
|
21
21
|
self.handler.agent.template_vars["role"] = new_role
|
22
22
|
# Refresh the system prompt with the new role if possible
|
23
|
-
|
24
|
-
|
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
|
-
)
|
23
|
+
self.handler.agent.refresh_system_prompt_from_template()
|
24
|
+
|
32
25
|
return f"Role set to: {new_role}"
|
33
26
|
|
34
27
|
def get_completions(self, document, complete_event):
|
@@ -28,8 +28,7 @@ class WriteShellHandler(ShellCmdHandler):
|
|
28
28
|
# Refresh system prompt if agent is available
|
29
29
|
agent = getattr(self.shell_state, "agent", None)
|
30
30
|
if agent:
|
31
|
-
|
32
|
-
agent._refresh_system_prompt_from_template()
|
31
|
+
agent.refresh_system_prompt_from_template()
|
33
32
|
# No need to print the system prompt after permission change
|
34
33
|
if enable:
|
35
34
|
shared_console.print("[green]Write permissions ENABLED. Tools can now write files and data.[/green]")
|
@@ -12,7 +12,7 @@ class UserInputHistory:
|
|
12
12
|
"""
|
13
13
|
|
14
14
|
def __init__(self, history_dir=None):
|
15
|
-
self.history_dir = history_dir or os.path.join(".janito", "input_history")
|
15
|
+
self.history_dir = history_dir or os.path.join(os.path.expanduser("~"), ".janito", "input_history")
|
16
16
|
os.makedirs(self.history_dir, exist_ok=True)
|
17
17
|
|
18
18
|
def _get_today_file(self):
|
@@ -40,71 +40,3 @@ def set_role(role):
|
|
40
40
|
rc.save()
|
41
41
|
|
42
42
|
|
43
|
-
def load_last_summary(path=".janito/last_conversation.json"):
|
44
|
-
if not os.path.exists(path):
|
45
|
-
return None
|
46
|
-
with open(path, "r", encoding="utf-8") as f:
|
47
|
-
data = json.load(f)
|
48
|
-
return data
|
49
|
-
|
50
|
-
|
51
|
-
def load_last_conversation(path=".janito/last_conversation.json"):
|
52
|
-
if not os.path.exists(path):
|
53
|
-
return [], [], None
|
54
|
-
with open(path, "r", encoding="utf-8") as f:
|
55
|
-
data = json.load(f)
|
56
|
-
messages = data.get("messages", [])
|
57
|
-
prompts = data.get("prompts", [])
|
58
|
-
usage = data.get("last_usage_info")
|
59
|
-
return messages, prompts, usage
|
60
|
-
|
61
|
-
|
62
|
-
def load_conversation_by_session_id(session_id):
|
63
|
-
path = os.path.join(".janito", "chat_history", f"{session_id}.json")
|
64
|
-
if not os.path.exists(path):
|
65
|
-
raise FileNotFoundError(f"Session file not found: {path}")
|
66
|
-
with open(path, "r", encoding="utf-8") as f:
|
67
|
-
data = json.load(f)
|
68
|
-
messages = data.get("messages", [])
|
69
|
-
prompts = data.get("prompts", [])
|
70
|
-
usage = data.get("last_usage_info")
|
71
|
-
return messages, prompts, usage
|
72
|
-
|
73
|
-
|
74
|
-
def save_conversation(messages, prompts, usage_info=None, path=None):
|
75
|
-
# Do not save if only one message and it is a system message (noop session)
|
76
|
-
if (
|
77
|
-
isinstance(messages, list)
|
78
|
-
and len(messages) == 1
|
79
|
-
and messages[0].get("role") == "system"
|
80
|
-
):
|
81
|
-
return
|
82
|
-
|
83
|
-
if path is None:
|
84
|
-
session_id = get_session_id()
|
85
|
-
path = os.path.join(".janito", "chat_history", f"{session_id}.json")
|
86
|
-
os.makedirs(os.path.dirname(path), exist_ok=True)
|
87
|
-
data = {"messages": messages, "prompts": prompts, "last_usage_info": usage_info}
|
88
|
-
|
89
|
-
def usage_serializer(obj):
|
90
|
-
if hasattr(obj, "to_dict"):
|
91
|
-
return obj.to_dict()
|
92
|
-
if hasattr(obj, "__dict"):
|
93
|
-
return obj.__dict__
|
94
|
-
return str(obj)
|
95
|
-
|
96
|
-
with open(path, "w", encoding="utf-8") as f:
|
97
|
-
json.dump(data, f, indent=2, default=usage_serializer)
|
98
|
-
f.write("\n")
|
99
|
-
|
100
|
-
|
101
|
-
def last_conversation_exists(path=".janito/last_conversation.json"):
|
102
|
-
if not os.path.exists(path):
|
103
|
-
return False
|
104
|
-
try:
|
105
|
-
with open(path, "r", encoding="utf-8") as f:
|
106
|
-
data = json.load(f)
|
107
|
-
messages = data.get("messages", [])
|
108
|
-
return bool(messages)
|
109
|
-
except Exception:
|
110
|
-
return False
|
janito/cli/core/runner.py
CHANGED
@@ -96,7 +96,7 @@ def prepare_llm_driver_config(args, modifiers):
|
|
96
96
|
return provider, llm_driver_config, agent_role
|
97
97
|
|
98
98
|
|
99
|
-
def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=False,
|
99
|
+
def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=False, ):
|
100
100
|
"""
|
101
101
|
Main runner for CLI execution. If exec_enabled is False, disables execution/run tools.
|
102
102
|
"""
|
@@ -108,7 +108,7 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
|
|
108
108
|
from janito.tools.tool_base import ToolPermissions
|
109
109
|
read = getattr(args, "read", False)
|
110
110
|
write = getattr(args, "write", False)
|
111
|
-
execute =
|
111
|
+
execute = getattr(args, "exec", False)
|
112
112
|
from janito.tools.permissions import set_global_allowed_permissions
|
113
113
|
from janito.tools.tool_base import ToolPermissions
|
114
114
|
allowed_permissions = ToolPermissions(read=read, write=write, execute=execute)
|
@@ -145,7 +145,7 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
|
|
145
145
|
handler = SingleShotPromptHandler(
|
146
146
|
args, provider_instance, llm_driver_config,
|
147
147
|
role=agent_role,
|
148
|
-
|
148
|
+
|
149
149
|
allowed_permissions=allowed_permissions,
|
150
150
|
)
|
151
151
|
handler.handle()
|
@@ -162,7 +162,7 @@ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=F
|
|
162
162
|
args=args,
|
163
163
|
verbose_tools=verbose_tools,
|
164
164
|
verbose_agent=getattr(args, "verbose_agent", False),
|
165
|
-
|
165
|
+
|
166
166
|
allowed_permissions=allowed_permissions,
|
167
167
|
)
|
168
168
|
session.run()
|
janito/cli/main_cli.py
CHANGED
@@ -200,6 +200,17 @@ class JanitoCLI:
|
|
200
200
|
self._define_args()
|
201
201
|
self.args = self.parser.parse_args()
|
202
202
|
self._set_all_arg_defaults()
|
203
|
+
# Support reading prompt from stdin if no user_prompt is given
|
204
|
+
import sys
|
205
|
+
if not sys.stdin.isatty():
|
206
|
+
stdin_input = sys.stdin.read().strip()
|
207
|
+
if stdin_input:
|
208
|
+
if self.args.user_prompt and len(self.args.user_prompt) > 0:
|
209
|
+
# Prefix the prompt argument to the stdin input
|
210
|
+
combined = ' '.join(self.args.user_prompt) + ' ' + stdin_input
|
211
|
+
self.args.user_prompt = [combined]
|
212
|
+
else:
|
213
|
+
self.args.user_prompt = [stdin_input]
|
203
214
|
from janito.cli.rich_terminal_reporter import RichTerminalReporter
|
204
215
|
|
205
216
|
self.rich_reporter = RichTerminalReporter(raw_mode=self.args.raw)
|
@@ -235,9 +246,6 @@ class JanitoCLI:
|
|
235
246
|
if getattr(self.args, k, None) is not None
|
236
247
|
}
|
237
248
|
|
238
|
-
def exec_enabled(self):
|
239
|
-
return getattr(self.args, "exec", False)
|
240
|
-
|
241
249
|
def classify(self):
|
242
250
|
if any(getattr(self.args, k, None) for k in SETTER_KEYS):
|
243
251
|
return RunMode.SET
|
@@ -291,8 +299,7 @@ class JanitoCLI:
|
|
291
299
|
llm_driver_config,
|
292
300
|
agent_role,
|
293
301
|
verbose_tools=self.args.verbose_tools,
|
294
|
-
|
295
|
-
)
|
302
|
+
)
|
296
303
|
elif run_mode == RunMode.GET:
|
297
304
|
handle_getter(self.args)
|
298
305
|
|
janito/cli/prompt_setup.py
CHANGED
@@ -21,7 +21,7 @@ def setup_agent_and_prompt_handler(
|
|
21
21
|
role: Optional[str] = None,
|
22
22
|
verbose_tools: bool = False,
|
23
23
|
verbose_agent: bool = False,
|
24
|
-
|
24
|
+
|
25
25
|
allowed_permissions: Optional[list[str]] = None,
|
26
26
|
profile: Optional[str] = None,
|
27
27
|
profile_system_prompt: Optional[str] = None,
|
@@ -40,7 +40,7 @@ def setup_agent_and_prompt_handler(
|
|
40
40
|
role=role,
|
41
41
|
verbose_tools=verbose_tools,
|
42
42
|
verbose_agent=verbose_agent,
|
43
|
-
|
43
|
+
|
44
44
|
allowed_permissions=allowed_permissions,
|
45
45
|
profile=profile,
|
46
46
|
profile_system_prompt=profile_system_prompt,
|
@@ -10,6 +10,8 @@ from janito.event_bus.bus import event_bus
|
|
10
10
|
from janito.llm import message_parts
|
11
11
|
|
12
12
|
|
13
|
+
import sys
|
14
|
+
|
13
15
|
class RichTerminalReporter(EventHandlerBase):
|
14
16
|
"""
|
15
17
|
Handles UI rendering for janito events using Rich.
|
@@ -63,8 +65,15 @@ class RichTerminalReporter(EventHandlerBase):
|
|
63
65
|
self.console.print(Markdown(part.content))
|
64
66
|
self.console.file.flush()
|
65
67
|
|
68
|
+
def delete_current_line(self):
|
69
|
+
"""
|
70
|
+
Clears the entire current line in the terminal and returns the cursor to column 1.
|
71
|
+
"""
|
72
|
+
sys.stdout.write('\033[2K\r')
|
73
|
+
sys.stdout.flush()
|
74
|
+
|
66
75
|
def on_RequestFinished(self, event):
|
67
|
-
self.
|
76
|
+
self.delete_current_line()
|
68
77
|
self._waiting_printed = False
|
69
78
|
response = getattr(event, "response", None)
|
70
79
|
error = getattr(event, "error", None)
|
@@ -99,14 +108,14 @@ class RichTerminalReporter(EventHandlerBase):
|
|
99
108
|
if not msg or not subtype:
|
100
109
|
return
|
101
110
|
if subtype == ReportSubtype.ACTION_INFO:
|
102
|
-
|
111
|
+
# Use orange for modification actions, cyan otherwise
|
112
|
+
modification_actions = (
|
103
113
|
getattr(ReportAction, "UPDATE", None),
|
104
114
|
getattr(ReportAction, "WRITE", None),
|
105
115
|
getattr(ReportAction, "DELETE", None),
|
106
|
-
)
|
107
|
-
|
108
|
-
|
109
|
-
self.console.print(msg, end="")
|
116
|
+
)
|
117
|
+
style = "orange1" if getattr(event, "action", None) in modification_actions else "cyan"
|
118
|
+
self.console.print(Text(msg, style=style), end="")
|
110
119
|
self.console.file.flush()
|
111
120
|
elif subtype in (
|
112
121
|
ReportSubtype.SUCCESS,
|
@@ -115,6 +124,12 @@ class RichTerminalReporter(EventHandlerBase):
|
|
115
124
|
):
|
116
125
|
self.console.print(msg)
|
117
126
|
self.console.file.flush()
|
127
|
+
elif subtype == ReportSubtype.STDOUT:
|
128
|
+
self.console.print(Text(msg, style="on dark_green"))
|
129
|
+
self.console.file.flush()
|
130
|
+
elif subtype == ReportSubtype.STDERR:
|
131
|
+
self.console.print(Text(msg, style="on red"))
|
132
|
+
self.console.file.flush()
|
118
133
|
else:
|
119
134
|
self.console.print(msg)
|
120
135
|
self.console.file.flush()
|
@@ -10,13 +10,12 @@ from janito.cli.console import shared_console
|
|
10
10
|
|
11
11
|
|
12
12
|
class PromptHandler:
|
13
|
-
def __init__(self, args, provider_instance, llm_driver_config, role=None,
|
13
|
+
def __init__(self, args, provider_instance, llm_driver_config, role=None, allowed_permissions=None):
|
14
14
|
self.args = args
|
15
15
|
self.provider_instance = provider_instance
|
16
16
|
self.llm_driver_config = llm_driver_config
|
17
17
|
self.role = role
|
18
|
-
|
19
|
-
# Instantiate agent together with prompt handler using the shared helper
|
18
|
+
# Instantiate agent together with prompt handler using the shared helper
|
20
19
|
self.agent, self.generic_handler = setup_agent_and_prompt_handler(
|
21
20
|
args=args,
|
22
21
|
provider_instance=provider_instance,
|
@@ -24,7 +23,7 @@ class PromptHandler:
|
|
24
23
|
role=role,
|
25
24
|
verbose_tools=getattr(args, "verbose_tools", False),
|
26
25
|
verbose_agent=getattr(args, "verbose_agent", False),
|
27
|
-
|
26
|
+
|
28
27
|
allowed_permissions=allowed_permissions,
|
29
28
|
profile=getattr(args, "profile", None),
|
30
29
|
)
|
@@ -42,13 +41,18 @@ class PromptHandler:
|
|
42
41
|
shared_console.print(
|
43
42
|
"[yellow]Warning: Some characters in your input were not valid UTF-8 and have been replaced.[/yellow]"
|
44
43
|
)
|
44
|
+
import time
|
45
45
|
try:
|
46
|
+
start_time = time.time()
|
46
47
|
self.generic_handler.handle_prompt(
|
47
48
|
sanitized,
|
48
49
|
args=self.args,
|
49
50
|
print_header=True,
|
50
51
|
raw=getattr(self.args, "raw", False),
|
51
52
|
)
|
53
|
+
end_time = time.time()
|
54
|
+
elapsed = end_time - start_time
|
55
|
+
self._post_prompt_actions(elapsed=elapsed)
|
52
56
|
if hasattr(self.args, "verbose_agent") and self.args.verbose_agent:
|
53
57
|
print("[debug] handle_prompt() completed without exception.")
|
54
58
|
except Exception as e:
|
@@ -56,14 +60,16 @@ class PromptHandler:
|
|
56
60
|
f"[error] Exception occurred in handle_prompt: {type(e).__name__}: {e}"
|
57
61
|
)
|
58
62
|
traceback.print_exc()
|
59
|
-
self._post_prompt_actions()
|
60
63
|
|
61
|
-
def _post_prompt_actions(self):
|
64
|
+
def _post_prompt_actions(self, elapsed=None):
|
62
65
|
# Align with chat mode: only print token usage summary
|
66
|
+
import sys
|
63
67
|
from janito.formatting_token import print_token_message_summary
|
64
68
|
from janito.perf_singleton import performance_collector
|
65
69
|
usage = performance_collector.get_last_request_usage()
|
66
|
-
|
70
|
+
# If running in stdin mode, do not print token usage
|
71
|
+
if sys.stdin.isatty():
|
72
|
+
print_token_message_summary(shared_console, msg_count=1, usage=usage, elapsed=elapsed)
|
67
73
|
self._cleanup_driver_and_console()
|
68
74
|
|
69
75
|
|
@@ -8,13 +8,11 @@ from typing import Dict, Type
|
|
8
8
|
# --- Import driver classes ---
|
9
9
|
from janito.drivers.anthropic.driver import AnthropicModelDriver
|
10
10
|
from janito.drivers.azure_openai.driver import AzureOpenAIModelDriver
|
11
|
-
from janito.drivers.mistralai.driver import MistralAIModelDriver
|
12
11
|
from janito.drivers.openai.driver import OpenAIModelDriver
|
13
12
|
|
14
13
|
_DRIVER_REGISTRY: Dict[str, Type] = {
|
15
14
|
"AnthropicModelDriver": AnthropicModelDriver,
|
16
15
|
"AzureOpenAIModelDriver": AzureOpenAIModelDriver,
|
17
|
-
"MistralAIModelDriver": MistralAIModelDriver,
|
18
16
|
"OpenAIModelDriver": OpenAIModelDriver,
|
19
17
|
}
|
20
18
|
|
janito/formatting_token.py
CHANGED
@@ -25,9 +25,9 @@ def format_tokens(n, tag=None, use_rich=False):
|
|
25
25
|
return val
|
26
26
|
|
27
27
|
|
28
|
-
def format_token_message_summary(msg_count, usage, width=96, use_rich=False):
|
28
|
+
def format_token_message_summary(msg_count, usage, width=96, use_rich=False, elapsed=None):
|
29
29
|
"""
|
30
|
-
Returns a string (rich or pt markup) summarizing message count
|
30
|
+
Returns a string (rich or pt markup) summarizing message count, last token usage, and elapsed time.
|
31
31
|
"""
|
32
32
|
left = f" Messages: {'[' if use_rich else '<'}msg_count{']' if use_rich else '>'}{msg_count}{'[/msg_count]' if use_rich else '</msg_count>'}"
|
33
33
|
tokens_part = ""
|
@@ -40,15 +40,16 @@ def format_token_message_summary(msg_count, usage, width=96, use_rich=False):
|
|
40
40
|
f"Completion: {format_tokens(completion_tokens, 'tokens_out', use_rich)}, "
|
41
41
|
f"Total: {format_tokens(total_tokens, 'tokens_total', use_rich)}"
|
42
42
|
)
|
43
|
-
|
43
|
+
elapsed_part = f" | Elapsed: [cyan]{elapsed:.2f}s[/cyan]" if elapsed is not None else ""
|
44
|
+
return f"{left}{tokens_part}{elapsed_part}"
|
44
45
|
|
45
46
|
|
46
|
-
def print_token_message_summary(console, msg_count=None, usage=None, width=96):
|
47
|
-
"""Prints the summary using rich markup, using defaults from perf_singleton if not given."""
|
47
|
+
def print_token_message_summary(console, msg_count=None, usage=None, width=96, elapsed=None):
|
48
|
+
"""Prints the summary using rich markup, using defaults from perf_singleton if not given. Optionally includes elapsed time."""
|
48
49
|
if usage is None:
|
49
50
|
usage = performance_collector.get_last_request_usage()
|
50
51
|
if msg_count is None:
|
51
52
|
msg_count = performance_collector.get_total_turns() or 0
|
52
|
-
line = format_token_message_summary(msg_count, usage, width, use_rich=True)
|
53
|
+
line = format_token_message_summary(msg_count, usage, width, use_rich=True, elapsed=elapsed)
|
53
54
|
if line.strip():
|
54
55
|
console.print(Rule(line))
|
janito/llm/agent.py
CHANGED
@@ -87,7 +87,7 @@ class LLMAgent:
|
|
87
87
|
template = env.get_template(Path(template_path).name)
|
88
88
|
self.system_prompt = template.render(**kwargs)
|
89
89
|
|
90
|
-
def
|
90
|
+
def refresh_system_prompt_from_template(self):
|
91
91
|
if hasattr(self, "_template_vars") and hasattr(self, "system_prompt_template"):
|
92
92
|
env = Environment(
|
93
93
|
loader=FileSystemLoader(Path(self.system_prompt_template).parent),
|
janito/provider_registry.py
CHANGED
@@ -130,7 +130,7 @@ class ProviderRegistry:
|
|
130
130
|
"openai": "janito.providers.openai.model_info",
|
131
131
|
"azure_openai": "janito.providers.azure_openai.model_info",
|
132
132
|
"google": "janito.providers.google.model_info",
|
133
|
-
|
133
|
+
|
134
134
|
"deepseek": "janito.providers.deepseek.model_info",
|
135
135
|
}
|
136
136
|
if provider_name in provider_to_specs:
|
janito/providers/__init__.py
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Ensure all providers are registered by importing their modules
|
2
2
|
import janito.providers.openai.provider
|
3
3
|
import janito.providers.google.provider
|
4
|
-
import janito.providers.mistralai.provider
|
5
|
-
import janito.providers.google.provider
|
6
4
|
import janito.providers.azure_openai.provider
|
7
5
|
import janito.providers.anthropic.provider
|
8
6
|
import janito.providers.deepseek.provider
|
janito/tools/tool_base.py
CHANGED
@@ -48,16 +48,6 @@ class ToolBase:
|
|
48
48
|
)
|
49
49
|
)
|
50
50
|
|
51
|
-
def report_info(self, message: str, context: dict = None):
|
52
|
-
self._event_bus.publish(
|
53
|
-
ReportEvent(
|
54
|
-
subtype=ReportSubtype.ACTION_INFO,
|
55
|
-
message=message,
|
56
|
-
action=None,
|
57
|
-
tool=self.name,
|
58
|
-
context=context,
|
59
|
-
)
|
60
|
-
)
|
61
51
|
|
62
52
|
def report_error(self, message: str, context: dict = None):
|
63
53
|
self._event_bus.publish(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: janito
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.5.1
|
4
4
|
Summary: A new Python package called janito.
|
5
5
|
Author-email: João Pinto <lamego.pinto@gmail.com>
|
6
6
|
Project-URL: Homepage, https://github.com/janito-dev/janito
|
@@ -167,19 +167,6 @@ Janito has configuration options, like `--set api-key API_KEY` and `--set provid
|
|
167
167
|
|
168
168
|
### Advanced Options
|
169
169
|
|
170
|
-
- **Enable Inline Web File Viewer for Clickable Links**
|
171
|
-
|
172
|
-
By default, Janito can open referenced files in a browser-based viewer when you click on file links in supported terminals. To enable this feature for your session, use the `--web` flag:
|
173
|
-
|
174
|
-
```bash
|
175
|
-
janito --web
|
176
|
-
```
|
177
|
-
|
178
|
-
This starts the lightweight web file viewer () in the background, allowing you to inspect files referenced in responses directly in your browser. Combine with interactive mode or prompts as needed.
|
179
|
-
|
180
|
-
> **Tip:** Use with the interactive shell for the best experience with clickable file links.
|
181
|
-
|
182
|
-
|
183
170
|
- **Enable Execution Tools (Code/Shell Execution)**
|
184
171
|
|
185
172
|
By default, **all tool privileges (read, write, execute)** are disabled for safety. This means Janito starts with no permissions to run tools that read, write, or execute code/shell commands unless you explicitly enable them.
|
@@ -232,7 +219,7 @@ janito -r -w -x "Run this code: print('Hello, world!')"
|
|
232
219
|
### Core CLI Options
|
233
220
|
| Option | Description |
|
234
221
|
|------------------------|-----------------------------------------------------------------------------|
|
235
|
-
|
222
|
+
|
236
223
|
| `--version` | Show program version |
|
237
224
|
| `--list-tools` | List all registered tools |
|
238
225
|
| `--list-providers` | List all supported LLM providers |
|
@@ -8,63 +8,66 @@ janito/dir_walk_utils.py,sha256=ON9EyVH7Aaik8WtCH5z8DQis9ycdoNVkjNvU16HH498,1193
|
|
8
8
|
janito/driver_events.py,sha256=51ab7KW_W6fVZVeO0ez-HJFY4NbTI327ZlEmEsEkxQc,3405
|
9
9
|
janito/exceptions.py,sha256=l4AepRdWwAuLp5fUygrBBgO9rpwgfV6JvY1afOdq2pw,913
|
10
10
|
janito/formatting.py,sha256=SMvOmL6bst3KGcI7OLa5D4DE127fQYuHZS3oY8OPsn8,2031
|
11
|
-
janito/formatting_token.py,sha256=
|
11
|
+
janito/formatting_token.py,sha256=ECZ9CNcOfQeutNMTZZTQrKm17pTgNpMAGVsNr7_EEnE,2167
|
12
12
|
janito/gitignore_utils.py,sha256=P3iF9fMWAomqULq2xsoqHtI9uNIFSPcagljrxZshmLw,4110
|
13
13
|
janito/perf_singleton.py,sha256=g1h0Sdf4ydzegeEpJlMhQt4H0GQZ2hryXrdYOTL-b30,113
|
14
14
|
janito/performance_collector.py,sha256=RYu4av16Trj3RljJZ8-2Gbn1KlGdJUosrcVFYtwviNI,6285
|
15
15
|
janito/platform_discovery.py,sha256=JN3kC7hkxdvuj-AyrJTlbbDJjtNHke3fdlZDqGi_uz0,4621
|
16
16
|
janito/provider_config.py,sha256=acn2FEgWsEIyi2AxZiuCLoP2rXDd-nXcP5VB4CZHaeE,3189
|
17
|
-
janito/provider_registry.py,sha256=
|
17
|
+
janito/provider_registry.py,sha256=THlyJLhAr0hTb4OuLHc7BcOjTYy0LG-THc-kZRk3PCI,7787
|
18
18
|
janito/report_events.py,sha256=q4OR_jTZNfcqaQF_fzTjgqo6_VlUIxSGWfhpT4nJWcw,938
|
19
19
|
janito/shell.bak.zip,sha256=hznHbmgfkAkjuQDJ3w73XPQh05yrtUZQxLmtGbanbYU,22
|
20
20
|
janito/utils.py,sha256=eXSsMgM69YyzahgCNrJQLcEbB8ssLI1MQqaa20ONxbE,376
|
21
|
-
janito/agent/setup_agent.py,sha256=
|
21
|
+
janito/agent/setup_agent.py,sha256=Q0scfZWoPu_juZMRjYJWpBX5z4Jev4_i5WZMqEuVBO4,8574
|
22
|
+
janito/agent/templates/profiles/system_prompt_template_assistant.txt.j2,sha256=dTV9aF8ji2r9dzi-l4b9r95kHrbKmjvnRxk5cVpopN4,28
|
22
23
|
janito/agent/templates/profiles/system_prompt_template_developer.txt.j2,sha256=gIXF3dPgGxQnVqRBnT8r2sUGu7F_Sl0F4YF-TfyOKgI,2586
|
23
24
|
janito/cli/__init__.py,sha256=xaPDOrWphBbCR63Xpcx_yfpXSJIlCaaICc4j2qpWqrM,194
|
24
25
|
janito/cli/config.py,sha256=t7sdM0I3RD_FZ2ni1xuGMFGzvCLMt3NwJKu3_WtxPUg,1068
|
25
26
|
janito/cli/console.py,sha256=gJolqzWL7jEPLxeuH-CwBDRFpXt976KdZOEAB2tdBDs,64
|
26
27
|
janito/cli/main.py,sha256=s5odou0txf8pzTf1ADk2yV7T5m8B6cejJ81e7iu776U,312
|
27
|
-
janito/cli/main_cli.py,sha256=
|
28
|
+
janito/cli/main_cli.py,sha256=t5AgysW_mfeLlrNhJpLhumUs65YCWzvN4gkJRmozlKU,12086
|
28
29
|
janito/cli/prompt_core.py,sha256=IAa1X4fw4aPASFyOXGiFcpgiZXlVoFQM617F0mHMxsE,11587
|
29
30
|
janito/cli/prompt_handler.py,sha256=SnPTlL64noeAMGlI08VBDD5IDD8jlVMIYA4-fS8zVLg,215
|
30
|
-
janito/cli/prompt_setup.py,sha256=
|
31
|
-
janito/cli/rich_terminal_reporter.py,sha256=
|
31
|
+
janito/cli/prompt_setup.py,sha256=PoRXIWEoVJ5DQtOLO0JCz_8cVVWp7zhKXQtXJuRGiQ4,1882
|
32
|
+
janito/cli/rich_terminal_reporter.py,sha256=xoZ_oeeqAr1f6a20OvQx9hKfNuWUX6vOAoUIL3_anUA,5552
|
32
33
|
janito/cli/utils.py,sha256=plCQiDKIf3V8mFhhX5H9-MF2W86i-xRdWf8Xi117Z0w,677
|
33
34
|
janito/cli/verbose_output.py,sha256=UmB1byT1V6wZvMJDIPfqajhmNcMnnJ3tgYocje5w0x8,7620
|
34
35
|
janito/cli/chat_mode/bindings.py,sha256=u8q8SekKyAFncoPI5mxeAQ2lI3loIEaUVyq2TqELv2c,1990
|
35
36
|
janito/cli/chat_mode/chat_entry.py,sha256=HjflAjGOz4xyRbzocsEzrjcVepfQYz3d9fzyZDMBB34,477
|
36
37
|
janito/cli/chat_mode/prompt_style.py,sha256=Yltxc9unsiWsJzfditE139iqL3S64d6G19LzrnqYvFg,825
|
37
|
-
janito/cli/chat_mode/
|
38
|
-
janito/cli/chat_mode/
|
38
|
+
janito/cli/chat_mode/script_runner.py,sha256=QwNIZWRPhlwsC4IOrh1rrZjTwMDeYGOByNZZVzg1tZk,6442
|
39
|
+
janito/cli/chat_mode/session.py,sha256=hwFilKshsZlR95ycX31clg4nD5DJiREmu9B-m02pbko,11941
|
40
|
+
janito/cli/chat_mode/session_profile_select.py,sha256=N_d1LMjXUS-ROQJaq0fTbPENxopXDuZwuLGCctg9Sd0,2894
|
39
41
|
janito/cli/chat_mode/toolbar.py,sha256=QWIVAdm31vNKu0UO_-igxYwVwtko-KzjtxPtK3DYH5Y,4891
|
40
42
|
janito/cli/chat_mode/shell/autocomplete.py,sha256=lE68MaVaodbA2VfUM0_YLqQVLBJAE_BJsd5cMtwuD-g,793
|
41
43
|
janito/cli/chat_mode/shell/commands.bak.zip,sha256=I7GFjXg2ORT5NzFpicH1vQ3kchhduQsZinzqo0xO8wU,74238
|
42
|
-
janito/cli/chat_mode/shell/input_history.py,sha256=
|
44
|
+
janito/cli/chat_mode/shell/input_history.py,sha256=EbfsZWzEkbW3VpWldN6Z885HwJq7QtxOveWaAmTamdg,2562
|
43
45
|
janito/cli/chat_mode/shell/session.bak.zip,sha256=m1GyO3Wy4G4D9sVgRO6ZDyC0VjclsmnEJsiQoer4LzI,5789
|
44
|
-
janito/cli/chat_mode/shell/commands/__init__.py,sha256=
|
46
|
+
janito/cli/chat_mode/shell/commands/__init__.py,sha256=T-t6JGDPTf7v6Ap4UT7spC0c0FbQ6YVXSVEesgbjycw,2390
|
45
47
|
janito/cli/chat_mode/shell/commands/_priv_check.py,sha256=LfIa_IbJBIhKT17K2cACbfYEJprFUH-o4BPvNnGyPSE,204
|
48
|
+
janito/cli/chat_mode/shell/commands/bang.py,sha256=PE79ZDKb9l4cFGbHLdJbpBcKmJRvhyFQQcCrtofY0HQ,1746
|
46
49
|
janito/cli/chat_mode/shell/commands/base.py,sha256=I6-SVOcRd7q4PpoutLdrbhbqeUpJic2oyPhOSMgMihA,288
|
47
50
|
janito/cli/chat_mode/shell/commands/clear.py,sha256=wYEHGYcAohUoCJlbEhiXKfDbJvuzAVK4e9uirskIllw,422
|
48
|
-
janito/cli/chat_mode/shell/commands/conversation_restart.py,sha256=
|
49
|
-
janito/cli/chat_mode/shell/commands/execute.py,sha256=
|
50
|
-
janito/cli/chat_mode/shell/commands/help.py,sha256=
|
51
|
+
janito/cli/chat_mode/shell/commands/conversation_restart.py,sha256=oid5wjvE7HoutS5OXzIXkHJUJSPZXbeR8tN2T0qvuI0,3638
|
52
|
+
janito/cli/chat_mode/shell/commands/execute.py,sha256=P1JeTRQDN0nYDO3qeE5NQsrSwY9tTlWUxbphbaGyqbY,2113
|
53
|
+
janito/cli/chat_mode/shell/commands/help.py,sha256=MvjnTskb7_z0aTbPML11Py2XYqBvLymzwIZgwE4bMpI,947
|
51
54
|
janito/cli/chat_mode/shell/commands/history_view.py,sha256=9dyxYpDHjT77LEIikjBQA03Ep3P2AmKXUwUnVsG0OQc,3584
|
52
55
|
janito/cli/chat_mode/shell/commands/lang.py,sha256=uIelDs3gPYDZ9X9gw7iDMmiwefT7TiBo32420pq2tW8,837
|
53
56
|
janito/cli/chat_mode/shell/commands/livelogs.py,sha256=uJI14qyubXEz8m0Cajd-vURPYxC__7p_CNCq6PVOHN0,2142
|
54
57
|
janito/cli/chat_mode/shell/commands/model.py,sha256=2tORoA5vdkAknbS9mnMi03gNKcLEkgmIuHPUHDGWxYo,1390
|
55
58
|
janito/cli/chat_mode/shell/commands/multi.py,sha256=HAAk0fAO3n8KFta3I4hT_scOAlz4SxWDyaNBUJBQ4nc,1985
|
56
|
-
janito/cli/chat_mode/shell/commands/prompt.py,sha256=
|
57
|
-
janito/cli/chat_mode/shell/commands/read.py,sha256=
|
58
|
-
janito/cli/chat_mode/shell/commands/role.py,sha256=
|
59
|
+
janito/cli/chat_mode/shell/commands/prompt.py,sha256=G3JTHXy1MiZ5TMIY_UrGCOGr9ZIsIE3i7cJ14m7YR4U,1794
|
60
|
+
janito/cli/chat_mode/shell/commands/read.py,sha256=pz1Nfa2xdFXxgwuxPfsW53-VgPRUm67h5ajHIWF4Vm0,1895
|
61
|
+
janito/cli/chat_mode/shell/commands/role.py,sha256=4Mt3okuNwOjqHbNhOFawcWB9KCLkpTDuLoDJFeXr3-E,1079
|
59
62
|
janito/cli/chat_mode/shell/commands/session.py,sha256=9wsw5U24-KJgTT70KAwnGuS8MVPyvpxCJfAt_Io76O0,1574
|
60
63
|
janito/cli/chat_mode/shell/commands/session_control.py,sha256=tmMGJ8IvWoBwSIJu7T6GPnFYFrmXWIG2Gr9tTni4y3U,1307
|
61
64
|
janito/cli/chat_mode/shell/commands/tools.py,sha256=G7tqjfkjXmTkMFIf6kHOhvYVq66LMPhGQdRyjpZO-xg,3190
|
62
65
|
janito/cli/chat_mode/shell/commands/utility.py,sha256=K982P-UwgPLzpEvSuSBGwiQ3zC34S_6T2ork_djweQw,847
|
63
66
|
janito/cli/chat_mode/shell/commands/verbose.py,sha256=HDTe0NhdcjBuhh-eJSW8iLPDeeBO95K5iSDAMAljxa4,953
|
64
|
-
janito/cli/chat_mode/shell/commands/write.py,sha256=
|
67
|
+
janito/cli/chat_mode/shell/commands/write.py,sha256=kBd04L32NVkwEyAi7DoXm6K5RshjB_apQ1q8M08KtLc,1905
|
65
68
|
janito/cli/chat_mode/shell/session/__init__.py,sha256=uTYE_QpZFEn7v9QE5o1LdulpCWa9vmk0OsefbBGWg_c,37
|
66
69
|
janito/cli/chat_mode/shell/session/history.py,sha256=tYav6GgjAZkvWhlI_rfG6OArNqW6Wn2DTv39Hb20QYc,1262
|
67
|
-
janito/cli/chat_mode/shell/session/manager.py,sha256=
|
70
|
+
janito/cli/chat_mode/shell/session/manager.py,sha256=m6cQe-9SeIqBnnWVEGtZiBtCpStqIwqRzP09XPhJrdM,1005
|
68
71
|
janito/cli/cli_commands/list_models.py,sha256=VN7_DG6aTxaHPrc6_H-OftRXRT1urhf5ze_qJ_SO35U,1116
|
69
72
|
janito/cli/cli_commands/list_providers.py,sha256=AMAVdoS7KN7WA3gaKhZZdfio_zvknu21OLDc6CTFZ34,173
|
70
73
|
janito/cli/cli_commands/list_tools.py,sha256=b-OG-lVV4B99bBc05qOrac3qoK8qDJJWGGLHAxsRwvo,4060
|
@@ -76,13 +79,13 @@ janito/cli/cli_commands/show_system_prompt.py,sha256=fbFWKWiIuI-UmYy39oHSZE3LBty
|
|
76
79
|
janito/cli/core/__init__.py,sha256=YH95fhgY9yBX8RgqX9dSrEkl4exjV0T4rbmJ6xUpG-Y,196
|
77
80
|
janito/cli/core/event_logger.py,sha256=1X6lR0Ax7AgF8HlPWFoY5Ystuu7Bh4ooTo78vXzeGB0,2008
|
78
81
|
janito/cli/core/getters.py,sha256=Znw6aF6QUHGu6UWqQHQYu7LvNPPIjOO4SD4yyYaIGnw,1467
|
79
|
-
janito/cli/core/runner.py,sha256=
|
82
|
+
janito/cli/core/runner.py,sha256=SOrwRpiOC81ja_ZiN1RelaXNhquvMuu6YIOyT_iLtwg,7144
|
80
83
|
janito/cli/core/setters.py,sha256=S3PxWPh0s7DAhbNyNRspbjtbd5EdAR-JNRe6X4jjIjE,7438
|
81
84
|
janito/cli/core/unsetters.py,sha256=FEw9gCt0vRvoCt0kRSNfVB2tzi_TqppJIx2nHPP59-k,2012
|
82
85
|
janito/cli/single_shot_mode/__init__.py,sha256=Ct99pKe9tINzVW6oedZJfzfZQKWpXz-weSSCn0hrwHY,115
|
83
|
-
janito/cli/single_shot_mode/handler.py,sha256=
|
86
|
+
janito/cli/single_shot_mode/handler.py,sha256=RtmkJVvF1j8FS7_HSlnuldUj2BzTf63rwGQ0KKhe4dU,3704
|
84
87
|
janito/drivers/dashscope.bak.zip,sha256=9Pv4Xyciju8jO1lEMFVgYXexoZkxmDO3Ig6vw3ODfL8,4936
|
85
|
-
janito/drivers/driver_registry.py,sha256=
|
88
|
+
janito/drivers/driver_registry.py,sha256=5ywB2CoNLsKB5D9ODVGVTCThbtskoUH_BvuRlHkK5Ew,890
|
86
89
|
janito/drivers/openai_responses.bak.zip,sha256=E43eDCHGa2tCtdjzj_pMnWDdnsOZzj8BJTR5tJp8wcM,13352
|
87
90
|
janito/drivers/anthropic/driver.py,sha256=4yLaf2T0g2zr-MSwXOx32s7ETut9FOl0uXyJGYiJzZU,3937
|
88
91
|
janito/drivers/azure_openai/driver.py,sha256=zQc9xH-RD409okDCfTRwb1QXXb9WzR2bsBfRyrZ5HYc,3936
|
@@ -99,7 +102,7 @@ janito/i18n/messages.py,sha256=fBuwOTFoygyHPkYphm6Y0r1iE8497Z4iryVAmPhMEkg,1851
|
|
99
102
|
janito/i18n/pt.py,sha256=NlTgpDSftUfFG7FGbs7TK54vQlJVMyaZDHGcWjelwMc,4168
|
100
103
|
janito/llm/README.md,sha256=6GRqCu_a9va5HCB1YqNqbshyWKFyAGlnXugrjom-xj8,1213
|
101
104
|
janito/llm/__init__.py,sha256=dpyVH51qVRCw-PDyAFLAxq0zd4jl5MDcuV6Cri0D-dQ,134
|
102
|
-
janito/llm/agent.py,sha256=
|
105
|
+
janito/llm/agent.py,sha256=isy-UfOiHq5LnNq_PmKTPuL5ZlTda52g6kjrZPdT_Ro,21253
|
103
106
|
janito/llm/auth.py,sha256=8Dl_orUEPhn2X6XjkO2Nr-j1HFT2YDxk1qJl9hSFI88,2286
|
104
107
|
janito/llm/driver.py,sha256=mepQ00QK0ouK8LHz4blQctUTolzlDatXNWWQEmSdpO8,10037
|
105
108
|
janito/llm/driver_config.py,sha256=OW0ae49EfgKDqaThuDjZBiaN78voNzwiZ6szERMqJos,1406
|
@@ -108,9 +111,9 @@ janito/llm/driver_input.py,sha256=Zq7IO4KdQPUraeIo6XoOaRy1IdQAyYY15RQw4JU30uA,38
|
|
108
111
|
janito/llm/message_parts.py,sha256=QY_0kDjaxdoErDgKPRPv1dNkkYJuXIBmHWNLiOEKAH4,1365
|
109
112
|
janito/llm/model.py,sha256=42hjcffZDTuzjAJoVhDcDqwIXm6rUmmi5UwTOYopf5w,1131
|
110
113
|
janito/llm/provider.py,sha256=lfIJnh06F0kf8--Pg_W7ALhkbIzn7N4iItQ93pntyuM,7978
|
111
|
-
janito/providers/__init__.py,sha256=
|
114
|
+
janito/providers/__init__.py,sha256=AY_mYBUuPP85TTIrx0-lMwbf8-biTLaCo_mZQBy0sck,282
|
112
115
|
janito/providers/dashscope.bak.zip,sha256=BwXxRmZreEivvRtmqbr5BR62IFVlNjAf4y6DrF2BVJo,5998
|
113
|
-
janito/providers/provider_static_info.py,sha256=
|
116
|
+
janito/providers/provider_static_info.py,sha256=CaidrKP062WrYAej27wIbSPK426t2iuufIUTNd6Sjug,497
|
114
117
|
janito/providers/registry.py,sha256=Ygwv9eVrTXOKhv0EKxSWQXO5WMHvajWE2Q_Lc3p7dKo,730
|
115
118
|
janito/providers/anthropic/model_info.py,sha256=saofXNs73WhlAhm58AcIkSem7C8FMUgHP19BvkoLV5Y,641
|
116
119
|
janito/providers/anthropic/provider.py,sha256=JW7PSGf7RNQWDMpf55DnnfP1oWU3d98koaz4AHjWtrQ,2509
|
@@ -135,7 +138,7 @@ janito/tools/inspect_registry.py,sha256=Jo7PrMPRKLuR-j_mBAk9PBcTzeJf1eQrS1ChGofg
|
|
135
138
|
janito/tools/outline_file.bak.zip,sha256=EeI2cBXCwTdWVgJDNiroxKeYlkjwo6NLKeXz3J-2iZI,15607
|
136
139
|
janito/tools/permissions.py,sha256=8lsfT7L6pyuvjZAgIXX5WrZZYSjZXPWUBpW7LXDBJ6M,1496
|
137
140
|
janito/tools/permissions_parse.py,sha256=OY_Uojjg_QCp6UsfVk5iHhrKRbeFgzfm8UUIoYDe18I,382
|
138
|
-
janito/tools/tool_base.py,sha256
|
141
|
+
janito/tools/tool_base.py,sha256=-yzl7Kki8eNlyyU-Z83ReXR-iJ0RkHpD6uksLYneyoE,3629
|
139
142
|
janito/tools/tool_events.py,sha256=czRtC2TYakAySBZvfHS_Q6_NY_7_krxzAzAL1ggRFWA,1527
|
140
143
|
janito/tools/tool_run_exception.py,sha256=43yWgTaGBGEtRteo6FvTrane6fEVGo9FU1uOdjMRWJE,525
|
141
144
|
janito/tools/tool_use_tracker.py,sha256=koXi1h-si8IpRFUdMaj6h6buxeYsuEDC4geP_f2xPms,2805
|
@@ -177,7 +180,7 @@ janito/tools/adapters/local/search_text/match_lines.py,sha256=2l0r8_1l5gnmu9vJSd
|
|
177
180
|
janito/tools/adapters/local/search_text/pattern_utils.py,sha256=Cytwl7M9tNY-IsAmvoMgvlQMPswbCHTVrX8aZQ6IBJc,2374
|
178
181
|
janito/tools/adapters/local/search_text/traverse_directory.py,sha256=TrsAlFXcG7WdtZS6pg3_6vlL3h-afps5u7kkBDhA65c,4064
|
179
182
|
janito/tools/adapters/local/validate_file_syntax/__init__.py,sha256=P53RHmas4BbHL90cMxH9m-RpMCJI8JquoJb0rpkPVVk,29
|
180
|
-
janito/tools/adapters/local/validate_file_syntax/core.py,sha256=
|
183
|
+
janito/tools/adapters/local/validate_file_syntax/core.py,sha256=Gqrvx0hPFnuzg0kQbLT-Z6ftF84Tkqq7o2c4CJDU4M8,3369
|
181
184
|
janito/tools/adapters/local/validate_file_syntax/css_validator.py,sha256=2yUMNxVIQy3AhuiahyZZbci0azMHkSWlGBbYIxJNJ-U,1361
|
182
185
|
janito/tools/adapters/local/validate_file_syntax/html_validator.py,sha256=sCIGBx-b-xz-vbz6pQM0rYYuzrt93_9ApC5zQ9Rwadk,3064
|
183
186
|
janito/tools/adapters/local/validate_file_syntax/js_validator.py,sha256=Km-wUrG0YZJ7kzxxyVPN_vXqOWIdfD12GkhQHPRVrC8,1008
|
@@ -187,9 +190,9 @@ janito/tools/adapters/local/validate_file_syntax/ps1_validator.py,sha256=cP1jsMh
|
|
187
190
|
janito/tools/adapters/local/validate_file_syntax/python_validator.py,sha256=lHzjlA4g9nCF9hXkGx3izWF0b0vJH3yV7Pu3buLyBbI,140
|
188
191
|
janito/tools/adapters/local/validate_file_syntax/xml_validator.py,sha256=3CK7BEGO7gKI3bpeTtCFe0kJ5aKDZVh3Kh67bGIhcuc,294
|
189
192
|
janito/tools/adapters/local/validate_file_syntax/yaml_validator.py,sha256=XLmOp7Ef6pLd97ICVnF3PxNKL1Yo5tLZsasvxPY478Y,165
|
190
|
-
janito-2.
|
191
|
-
janito-2.
|
192
|
-
janito-2.
|
193
|
-
janito-2.
|
194
|
-
janito-2.
|
195
|
-
janito-2.
|
193
|
+
janito-2.5.1.dist-info/licenses/LICENSE,sha256=GSAKapQH5ZIGWlpQTA7v5YrfECyaxaohUb1vJX-qepw,1090
|
194
|
+
janito-2.5.1.dist-info/METADATA,sha256=HX7_vYERiZRZ0svylDcdPZpv4QPHFP2SH3BbmSyx18E,16364
|
195
|
+
janito-2.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
196
|
+
janito-2.5.1.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
|
197
|
+
janito-2.5.1.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
|
198
|
+
janito-2.5.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|