janito 3.9.0__py3-none-any.whl → 3.10.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/agent_events.py +75 -0
- janito/cli/chat_mode/session.py +1 -0
- janito/cli/chat_mode/shell/commands/__init__.py +2 -0
- janito/cli/chat_mode/shell/commands/interactive.py +33 -0
- janito/cli/chat_mode/toolbar.py +16 -1
- janito/cli/core/runner.py +33 -0
- janito/cli/main_cli.py +9 -0
- janito/cli/prompt_core.py +301 -302
- janito/cli/rich_terminal_reporter.py +170 -179
- janito/cli/single_shot_mode/handler.py +19 -0
- janito/llm/agent.py +59 -0
- janito/plugins/tools/local/__init__.py +7 -0
- janito/plugins/tools/local/create_directory.py +44 -1
- janito/tests/test_tool_adapter_case_insensitive.py +112 -0
- janito/tools/tools_adapter.py +514 -510
- {janito-3.9.0.dist-info → janito-3.10.0.dist-info}/METADATA +84 -84
- {janito-3.9.0.dist-info → janito-3.10.0.dist-info}/RECORD +21 -18
- {janito-3.9.0.dist-info → janito-3.10.0.dist-info}/WHEEL +0 -0
- {janito-3.9.0.dist-info → janito-3.10.0.dist-info}/entry_points.txt +0 -0
- {janito-3.9.0.dist-info → janito-3.10.0.dist-info}/licenses/LICENSE +0 -0
- {janito-3.9.0.dist-info → janito-3.10.0.dist-info}/top_level.txt +0 -0
janito/agent_events.py
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
import attr
|
2
|
+
from typing import Any, ClassVar, Optional
|
3
|
+
from janito.event_bus.event import Event
|
4
|
+
|
5
|
+
|
6
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
7
|
+
class AgentEvent(Event):
|
8
|
+
"""
|
9
|
+
Base class for events related to an agent.
|
10
|
+
Includes agent name for identification.
|
11
|
+
"""
|
12
|
+
|
13
|
+
category: ClassVar[str] = "agent"
|
14
|
+
agent_name: Optional[str] = None
|
15
|
+
|
16
|
+
|
17
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
18
|
+
class AgentInitialized(AgentEvent):
|
19
|
+
"""Emitted when an agent is initialized."""
|
20
|
+
pass
|
21
|
+
|
22
|
+
|
23
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
24
|
+
class AgentChatStarted(AgentEvent):
|
25
|
+
"""Emitted when an agent starts a chat session."""
|
26
|
+
prompt: Optional[str] = None
|
27
|
+
messages: Optional[list] = None
|
28
|
+
role: Optional[str] = None
|
29
|
+
|
30
|
+
|
31
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
32
|
+
class AgentChatFinished(AgentEvent):
|
33
|
+
"""Emitted when an agent completes a chat session."""
|
34
|
+
result: Any = None
|
35
|
+
loop_count: int = 0
|
36
|
+
|
37
|
+
|
38
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
39
|
+
class AgentProcessingResponse(AgentEvent):
|
40
|
+
"""Emitted when an agent is processing a response."""
|
41
|
+
response: Any = None
|
42
|
+
|
43
|
+
|
44
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
45
|
+
class AgentToolCallStarted(AgentEvent):
|
46
|
+
"""Emitted when an agent starts processing a tool call."""
|
47
|
+
tool_call_id: Optional[str] = None
|
48
|
+
name: Optional[str] = None
|
49
|
+
arguments: Any = None
|
50
|
+
|
51
|
+
|
52
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
53
|
+
class AgentToolCallFinished(AgentEvent):
|
54
|
+
"""Emitted when an agent completes processing a tool call."""
|
55
|
+
tool_call_id: Optional[str] = None
|
56
|
+
name: Optional[str] = None
|
57
|
+
result: Any = None
|
58
|
+
|
59
|
+
|
60
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
61
|
+
class AgentWaitingForResponse(AgentEvent):
|
62
|
+
"""Emitted when an agent is waiting for a response from the LLM API."""
|
63
|
+
pass
|
64
|
+
|
65
|
+
|
66
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
67
|
+
class AgentReceivedResponse(AgentEvent):
|
68
|
+
"""Emitted when an agent receives a response from the LLM API."""
|
69
|
+
response: Any = None
|
70
|
+
|
71
|
+
|
72
|
+
@attr.s(auto_attribs=True, kw_only=True)
|
73
|
+
class AgentShutdown(AgentEvent):
|
74
|
+
"""Emitted when an agent is shutting down."""
|
75
|
+
pass
|
janito/cli/chat_mode/session.py
CHANGED
@@ -11,6 +11,7 @@ from .session import HistoryShellHandler
|
|
11
11
|
from .tools import ToolsShellHandler
|
12
12
|
from .help import HelpShellHandler
|
13
13
|
from .security_command import SecurityCommand
|
14
|
+
from .interactive import InteractiveShellHandler
|
14
15
|
from janito.cli.console import shared_console
|
15
16
|
|
16
17
|
COMMAND_HANDLERS = {
|
@@ -45,6 +46,7 @@ COMMAND_HANDLERS = {
|
|
45
46
|
"/help": HelpShellHandler,
|
46
47
|
"/security": SecurityCommand,
|
47
48
|
"/provider": ProviderCmdHandler,
|
49
|
+
"/interactive": InteractiveShellHandler,
|
48
50
|
}
|
49
51
|
|
50
52
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
2
|
+
from janito.cli.console import shared_console
|
3
|
+
|
4
|
+
|
5
|
+
class InteractiveShellHandler(ShellCmdHandler):
|
6
|
+
help_text = "Toggle interactive mode on/off"
|
7
|
+
|
8
|
+
def run(self):
|
9
|
+
args = self.after_cmd_line.strip().lower()
|
10
|
+
|
11
|
+
if args not in ["on", "off"]:
|
12
|
+
shared_console.print(
|
13
|
+
"[bold red]Usage: /interactive on|off[/bold red]"
|
14
|
+
)
|
15
|
+
return
|
16
|
+
|
17
|
+
# Get current interactive state from shell_state if available
|
18
|
+
current_state = getattr(self.shell_state, 'interactive_mode', True)
|
19
|
+
|
20
|
+
if args == "on":
|
21
|
+
if current_state:
|
22
|
+
shared_console.print("[yellow]Interactive mode is already enabled.[/yellow]")
|
23
|
+
else:
|
24
|
+
if hasattr(self.shell_state, 'interactive_mode'):
|
25
|
+
self.shell_state.interactive_mode = True
|
26
|
+
shared_console.print("[green]Interactive mode enabled.[/green]")
|
27
|
+
elif args == "off":
|
28
|
+
if not current_state:
|
29
|
+
shared_console.print("[yellow]Interactive mode is already disabled.[/yellow]")
|
30
|
+
else:
|
31
|
+
if hasattr(self.shell_state, 'interactive_mode'):
|
32
|
+
self.shell_state.interactive_mode = False
|
33
|
+
shared_console.print("[green]Interactive mode disabled.[/green]")
|
janito/cli/chat_mode/toolbar.py
CHANGED
@@ -51,6 +51,20 @@ def assemble_bindings_line(width, permissions=None):
|
|
51
51
|
)
|
52
52
|
|
53
53
|
|
54
|
+
def assemble_platform_line():
|
55
|
+
import platform
|
56
|
+
import sys
|
57
|
+
from janito.platform_discovery import PlatformDiscovery
|
58
|
+
|
59
|
+
discovery = PlatformDiscovery()
|
60
|
+
system_info = f"{platform.system()} {platform.release()}"
|
61
|
+
arch_info = platform.machine()
|
62
|
+
shell_info = discovery.detect_shell()
|
63
|
+
python_version = f"Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
64
|
+
|
65
|
+
return f" Platform: {system_info} ({arch_info}) | Shell: {shell_info} | {python_version}"
|
66
|
+
|
67
|
+
|
54
68
|
def _get_status(shell_state):
|
55
69
|
_support = getattr(shell_state, "_support", False)
|
56
70
|
_status = getattr(shell_state, "_status", None)
|
@@ -96,7 +110,8 @@ def get_toolbar_func(perf: PerformanceCollector, msg_count: int, shell_state):
|
|
96
110
|
first_line = assemble_first_line(provider_name, model_name, role, agent=agent)
|
97
111
|
permissions = _get_permissions()
|
98
112
|
bindings_line = assemble_bindings_line(width, permissions)
|
99
|
-
|
113
|
+
platform_line = assemble_platform_line()
|
114
|
+
toolbar_text = first_line + "\n" + platform_line + "\n" + bindings_line
|
100
115
|
|
101
116
|
return HTML(toolbar_text)
|
102
117
|
|
janito/cli/core/runner.py
CHANGED
@@ -38,6 +38,16 @@ def _choose_provider(args):
|
|
38
38
|
return provider
|
39
39
|
|
40
40
|
|
41
|
+
def _select_coder_model_for_provider(provider: str) -> str:
|
42
|
+
"""Auto-select the best coder model for the given provider when --developer mode is used."""
|
43
|
+
coder_models = {
|
44
|
+
"alibaba": "qwen3-coder-plus",
|
45
|
+
"cerebras": "qwen-3-coder-480b",
|
46
|
+
}
|
47
|
+
|
48
|
+
return coder_models.get(provider)
|
49
|
+
|
50
|
+
|
41
51
|
def _populate_driver_config_data(args, modifiers, provider, model):
|
42
52
|
from janito.provider_config import get_effective_setting
|
43
53
|
|
@@ -80,6 +90,17 @@ def prepare_llm_driver_config(args, modifiers):
|
|
80
90
|
if not model:
|
81
91
|
model = get_effective_model(provider)
|
82
92
|
|
93
|
+
# Auto-select coder model when --developer mode is used and no model is specified
|
94
|
+
if not model and getattr(args, "developer", False):
|
95
|
+
model = _select_coder_model_for_provider(provider)
|
96
|
+
if model and getattr(args, "verbose", False):
|
97
|
+
print_verbose_info(
|
98
|
+
"Auto-selected coder model",
|
99
|
+
f"{model} for provider {provider} (developer mode)",
|
100
|
+
style="magenta",
|
101
|
+
align_content=True,
|
102
|
+
)
|
103
|
+
|
83
104
|
# Validate that the chosen model is supported by the selected provider
|
84
105
|
if model:
|
85
106
|
from janito.provider_registry import ProviderRegistry
|
@@ -149,6 +170,15 @@ def handle_runner(
|
|
149
170
|
|
150
171
|
load_disabled_tools_from_config()
|
151
172
|
|
173
|
+
# Disable bash tools when running in PowerShell
|
174
|
+
from janito.platform_discovery import PlatformDiscovery
|
175
|
+
|
176
|
+
pd = PlatformDiscovery()
|
177
|
+
if pd.detect_shell().startswith("PowerShell"):
|
178
|
+
from janito.tools.disabled_tools import DisabledToolsState
|
179
|
+
|
180
|
+
DisabledToolsState.disable_tool("run_bash_command")
|
181
|
+
|
152
182
|
unrestricted = getattr(args, "unrestricted", False)
|
153
183
|
adapter = janito.tools.get_local_tools_adapter(
|
154
184
|
workdir=getattr(args, "workdir", None)
|
@@ -230,4 +260,7 @@ def handle_runner(
|
|
230
260
|
|
231
261
|
|
232
262
|
def get_prompt_mode(args):
|
263
|
+
# If interactive flag is set, force chat mode regardless of user_prompt
|
264
|
+
if getattr(args, "interactive", False):
|
265
|
+
return "chat_mode"
|
233
266
|
return "single_shot" if getattr(args, "user_prompt", None) else "chat_mode"
|
janito/cli/main_cli.py
CHANGED
@@ -204,6 +204,13 @@ definition = [
|
|
204
204
|
"help": "Enable emoji usage in responses to make output more engaging and expressive",
|
205
205
|
},
|
206
206
|
),
|
207
|
+
(
|
208
|
+
["-i", "--interactive"],
|
209
|
+
{
|
210
|
+
"action": "store_true",
|
211
|
+
"help": "Signal that this is an interactive chat session",
|
212
|
+
},
|
213
|
+
),
|
207
214
|
(["user_prompt"], {"nargs": argparse.REMAINDER, "help": "Prompt to submit"}),
|
208
215
|
(
|
209
216
|
["-e", "--event-log"],
|
@@ -256,6 +263,7 @@ MODIFIER_KEYS = [
|
|
256
263
|
"read",
|
257
264
|
"write",
|
258
265
|
"emoji",
|
266
|
+
"interactive",
|
259
267
|
]
|
260
268
|
SETTER_KEYS = ["set", "set_provider", "set_api_key", "unset"]
|
261
269
|
GETTER_KEYS = [
|
@@ -420,6 +428,7 @@ class JanitoCLI:
|
|
420
428
|
|
421
429
|
# If running in single shot mode and --profile is not provided, default to 'developer' profile
|
422
430
|
# Skip profile selection for list commands that don't need it
|
431
|
+
# Also skip if interactive mode is enabled (forces chat mode)
|
423
432
|
if get_prompt_mode(self.args) == "single_shot" and not getattr(
|
424
433
|
self.args, "profile", None
|
425
434
|
):
|