janito 1.14.3__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- janito/__init__.py +6 -1
- janito/__main__.py +1 -1
- janito/agent/setup_agent.py +139 -0
- janito/agent/templates/profiles/{system_prompt_template_base.txt.j2 → system_prompt_template_main.txt.j2} +1 -1
- janito/cli/__init__.py +9 -0
- janito/cli/chat_mode/bindings.py +37 -0
- janito/cli/chat_mode/chat_entry.py +23 -0
- janito/cli/chat_mode/prompt_style.py +19 -0
- janito/cli/chat_mode/session.py +272 -0
- janito/{shell/prompt/completer.py → cli/chat_mode/shell/autocomplete.py} +7 -6
- janito/cli/chat_mode/shell/commands/__init__.py +55 -0
- janito/cli/chat_mode/shell/commands/base.py +9 -0
- janito/cli/chat_mode/shell/commands/clear.py +12 -0
- janito/{shell → cli/chat_mode/shell}/commands/conversation_restart.py +34 -30
- janito/cli/chat_mode/shell/commands/edit.py +25 -0
- janito/cli/chat_mode/shell/commands/help.py +16 -0
- janito/cli/chat_mode/shell/commands/history_view.py +93 -0
- janito/cli/chat_mode/shell/commands/lang.py +25 -0
- janito/cli/chat_mode/shell/commands/last.py +137 -0
- janito/cli/chat_mode/shell/commands/livelogs.py +49 -0
- janito/cli/chat_mode/shell/commands/multi.py +51 -0
- janito/cli/chat_mode/shell/commands/prompt.py +64 -0
- janito/cli/chat_mode/shell/commands/role.py +36 -0
- janito/cli/chat_mode/shell/commands/session.py +40 -0
- janito/{shell → cli/chat_mode/shell}/commands/session_control.py +2 -2
- janito/cli/chat_mode/shell/commands/termweb_log.py +92 -0
- janito/cli/chat_mode/shell/commands/tools.py +32 -0
- janito/{shell → cli/chat_mode/shell}/commands/utility.py +4 -7
- janito/{shell → cli/chat_mode/shell}/commands/verbose.py +5 -5
- janito/cli/chat_mode/shell/session/__init__.py +1 -0
- janito/{shell → cli/chat_mode/shell}/session/manager.py +9 -1
- janito/cli/chat_mode/toolbar.py +90 -0
- janito/cli/cli_commands/list_models.py +35 -0
- janito/cli/cli_commands/list_providers.py +9 -0
- janito/cli/cli_commands/list_tools.py +53 -0
- janito/cli/cli_commands/model_selection.py +50 -0
- janito/cli/cli_commands/model_utils.py +84 -0
- janito/cli/cli_commands/set_api_key.py +19 -0
- janito/cli/cli_commands/show_config.py +51 -0
- janito/cli/cli_commands/show_system_prompt.py +62 -0
- janito/cli/config.py +28 -0
- janito/cli/console.py +3 -0
- janito/cli/core/__init__.py +4 -0
- janito/cli/core/event_logger.py +59 -0
- janito/cli/core/getters.py +31 -0
- janito/cli/core/runner.py +141 -0
- janito/cli/core/setters.py +174 -0
- janito/cli/core/unsetters.py +54 -0
- janito/cli/main.py +8 -196
- janito/cli/main_cli.py +312 -0
- janito/cli/prompt_core.py +230 -0
- janito/cli/prompt_handler.py +6 -0
- janito/cli/rich_terminal_reporter.py +101 -0
- janito/cli/single_shot_mode/__init__.py +6 -0
- janito/cli/single_shot_mode/handler.py +137 -0
- janito/cli/termweb_starter.py +73 -24
- janito/cli/utils.py +25 -0
- janito/cli/verbose_output.py +196 -0
- janito/config.py +5 -0
- janito/config_manager.py +110 -0
- janito/conversation_history.py +30 -0
- janito/{agent/tools_utils/dir_walk_utils.py → dir_walk_utils.py} +3 -2
- janito/driver_events.py +98 -0
- janito/drivers/anthropic/driver.py +113 -0
- janito/drivers/azure_openai/driver.py +36 -0
- janito/drivers/driver_registry.py +33 -0
- janito/drivers/google_genai/driver.py +54 -0
- janito/drivers/google_genai/schema_generator.py +67 -0
- janito/drivers/mistralai/driver.py +41 -0
- janito/drivers/openai/driver.py +334 -0
- janito/event_bus/__init__.py +2 -0
- janito/event_bus/bus.py +68 -0
- janito/event_bus/event.py +15 -0
- janito/event_bus/handler.py +31 -0
- janito/event_bus/queue_bus.py +57 -0
- janito/exceptions.py +23 -0
- janito/formatting_token.py +54 -0
- janito/i18n/pt.py +1 -0
- janito/llm/__init__.py +5 -0
- janito/llm/agent.py +443 -0
- janito/llm/auth.py +62 -0
- janito/llm/driver.py +239 -0
- janito/llm/driver_config.py +34 -0
- janito/llm/driver_config_builder.py +34 -0
- janito/llm/driver_input.py +12 -0
- janito/llm/message_parts.py +60 -0
- janito/llm/model.py +38 -0
- janito/llm/provider.py +187 -0
- janito/perf_singleton.py +3 -0
- janito/performance_collector.py +167 -0
- janito/provider_config.py +98 -0
- janito/provider_registry.py +152 -0
- janito/providers/__init__.py +7 -0
- janito/providers/anthropic/model_info.py +22 -0
- janito/providers/anthropic/provider.py +65 -0
- janito/providers/azure_openai/model_info.py +15 -0
- janito/providers/azure_openai/provider.py +72 -0
- janito/providers/deepseek/__init__.py +1 -0
- janito/providers/deepseek/model_info.py +16 -0
- janito/providers/deepseek/provider.py +91 -0
- janito/providers/google/__init__.py +1 -0
- janito/providers/google/model_info.py +40 -0
- janito/providers/google/provider.py +69 -0
- janito/providers/mistralai/model_info.py +37 -0
- janito/providers/mistralai/provider.py +69 -0
- janito/providers/openai/__init__.py +1 -0
- janito/providers/openai/model_info.py +137 -0
- janito/providers/openai/provider.py +107 -0
- janito/providers/openai/schema_generator.py +63 -0
- janito/providers/provider_static_info.py +21 -0
- janito/providers/registry.py +26 -0
- janito/report_events.py +38 -0
- janito/termweb/app.py +1 -1
- janito/tools/__init__.py +16 -0
- janito/tools/adapters/__init__.py +1 -0
- janito/tools/adapters/local/__init__.py +54 -0
- janito/tools/adapters/local/adapter.py +92 -0
- janito/{agent/tools → tools/adapters/local}/ask_user.py +30 -13
- janito/tools/adapters/local/copy_file.py +84 -0
- janito/{agent/tools → tools/adapters/local}/create_directory.py +11 -10
- janito/tools/adapters/local/create_file.py +82 -0
- janito/tools/adapters/local/delete_text_in_file.py +136 -0
- janito/{agent/tools → tools/adapters/local}/fetch_url.py +18 -19
- janito/tools/adapters/local/find_files.py +140 -0
- janito/tools/adapters/local/get_file_outline/core.py +151 -0
- janito/{agent/tools → tools/adapters/local}/get_file_outline/python_outline.py +125 -0
- janito/tools/adapters/local/get_file_outline/python_outline_v2.py +156 -0
- janito/{agent/tools → tools/adapters/local}/get_file_outline/search_outline.py +12 -7
- janito/{agent/tools → tools/adapters/local}/move_file.py +13 -9
- janito/{agent/tools → tools/adapters/local}/open_url.py +7 -5
- janito/tools/adapters/local/python_code_run.py +165 -0
- janito/tools/adapters/local/python_command_run.py +163 -0
- janito/tools/adapters/local/python_file_run.py +162 -0
- janito/{agent/tools → tools/adapters/local}/remove_directory.py +15 -9
- janito/{agent/tools → tools/adapters/local}/remove_file.py +17 -14
- janito/{agent/tools → tools/adapters/local}/replace_text_in_file.py +27 -22
- janito/tools/adapters/local/run_bash_command.py +176 -0
- janito/tools/adapters/local/run_powershell_command.py +219 -0
- janito/{agent/tools → tools/adapters/local}/search_text/core.py +32 -12
- janito/{agent/tools → tools/adapters/local}/search_text/match_lines.py +13 -4
- janito/{agent/tools → tools/adapters/local}/search_text/pattern_utils.py +12 -4
- janito/{agent/tools → tools/adapters/local}/search_text/traverse_directory.py +15 -2
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/core.py +12 -11
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/css_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/html_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/js_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/json_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/markdown_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/ps1_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/python_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/xml_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/yaml_validator.py +1 -1
- janito/{agent/tools/get_lines.py → tools/adapters/local/view_file.py} +45 -27
- janito/tools/inspect_registry.py +17 -0
- janito/tools/tool_base.py +105 -0
- janito/tools/tool_events.py +58 -0
- janito/tools/tool_run_exception.py +12 -0
- janito/{agent → tools}/tool_use_tracker.py +2 -4
- janito/{agent/tools_utils/utils.py → tools/tool_utils.py} +18 -9
- janito/tools/tools_adapter.py +207 -0
- janito/tools/tools_schema.py +104 -0
- janito/utils.py +11 -0
- janito/version.py +4 -0
- janito-2.0.0.dist-info/METADATA +232 -0
- janito-2.0.0.dist-info/RECORD +180 -0
- janito/agent/__init__.py +0 -0
- janito/agent/api_exceptions.py +0 -4
- janito/agent/config.py +0 -147
- janito/agent/config_defaults.py +0 -12
- janito/agent/config_utils.py +0 -0
- janito/agent/content_handler.py +0 -0
- janito/agent/conversation.py +0 -238
- janito/agent/conversation_api.py +0 -306
- janito/agent/conversation_exceptions.py +0 -18
- janito/agent/conversation_tool_calls.py +0 -39
- janito/agent/conversation_ui.py +0 -17
- janito/agent/event.py +0 -24
- janito/agent/event_dispatcher.py +0 -24
- janito/agent/event_handler_protocol.py +0 -5
- janito/agent/event_system.py +0 -15
- janito/agent/llm_conversation_history.py +0 -82
- janito/agent/message_handler.py +0 -20
- janito/agent/message_handler_protocol.py +0 -5
- janito/agent/openai_client.py +0 -149
- janito/agent/openai_schema_generator.py +0 -187
- janito/agent/profile_manager.py +0 -96
- janito/agent/queued_message_handler.py +0 -50
- janito/agent/rich_live.py +0 -32
- janito/agent/rich_message_handler.py +0 -115
- janito/agent/runtime_config.py +0 -36
- janito/agent/test_handler_protocols.py +0 -47
- janito/agent/test_openai_schema_generator.py +0 -93
- janito/agent/tests/__init__.py +0 -1
- janito/agent/tool_base.py +0 -63
- janito/agent/tool_executor.py +0 -122
- janito/agent/tool_registry.py +0 -49
- janito/agent/tools/__init__.py +0 -47
- janito/agent/tools/create_file.py +0 -59
- janito/agent/tools/delete_text_in_file.py +0 -97
- janito/agent/tools/find_files.py +0 -106
- janito/agent/tools/get_file_outline/core.py +0 -81
- janito/agent/tools/present_choices.py +0 -64
- janito/agent/tools/python_command_runner.py +0 -201
- janito/agent/tools/python_file_runner.py +0 -199
- janito/agent/tools/python_stdin_runner.py +0 -208
- janito/agent/tools/replace_file.py +0 -72
- janito/agent/tools/run_bash_command.py +0 -218
- janito/agent/tools/run_powershell_command.py +0 -251
- janito/agent/tools_utils/__init__.py +0 -1
- janito/agent/tools_utils/action_type.py +0 -7
- janito/agent/tools_utils/test_gitignore_utils.py +0 -46
- janito/cli/_livereload_log_utils.py +0 -13
- janito/cli/_print_config.py +0 -96
- janito/cli/_termweb_log_utils.py +0 -17
- janito/cli/_utils.py +0 -9
- janito/cli/arg_parser.py +0 -272
- janito/cli/cli_main.py +0 -281
- janito/cli/config_commands.py +0 -211
- janito/cli/config_runner.py +0 -35
- janito/cli/formatting_runner.py +0 -12
- janito/cli/livereload_starter.py +0 -60
- janito/cli/logging_setup.py +0 -38
- janito/cli/one_shot.py +0 -80
- janito/livereload/app.py +0 -25
- janito/rich_utils.py +0 -59
- janito/shell/__init__.py +0 -0
- janito/shell/commands/__init__.py +0 -61
- janito/shell/commands/config.py +0 -22
- janito/shell/commands/edit.py +0 -24
- janito/shell/commands/history_view.py +0 -18
- janito/shell/commands/lang.py +0 -19
- janito/shell/commands/livelogs.py +0 -42
- janito/shell/commands/prompt.py +0 -62
- janito/shell/commands/termweb_log.py +0 -94
- janito/shell/commands/tools.py +0 -26
- janito/shell/commands/track.py +0 -36
- janito/shell/main.py +0 -326
- janito/shell/prompt/load_prompt.py +0 -57
- janito/shell/prompt/session_setup.py +0 -57
- janito/shell/session/config.py +0 -109
- janito/shell/session/history.py +0 -0
- janito/shell/ui/interactive.py +0 -226
- janito/termweb/static/editor.css +0 -158
- janito/termweb/static/editor.css.bak +0 -145
- janito/termweb/static/editor.html +0 -46
- janito/termweb/static/editor.html.bak +0 -46
- janito/termweb/static/editor.js +0 -265
- janito/termweb/static/editor.js.bak +0 -259
- janito/termweb/static/explorer.html.bak +0 -59
- janito/termweb/static/favicon.ico +0 -0
- janito/termweb/static/favicon.ico.bak +0 -0
- janito/termweb/static/index.html +0 -53
- janito/termweb/static/index.html.bak +0 -54
- janito/termweb/static/index.html.bak.bak +0 -175
- janito/termweb/static/landing.html.bak +0 -36
- janito/termweb/static/termicon.svg +0 -1
- janito/termweb/static/termweb.css +0 -214
- janito/termweb/static/termweb.css.bak +0 -237
- janito/termweb/static/termweb.js +0 -162
- janito/termweb/static/termweb.js.bak +0 -168
- janito/termweb/static/termweb.js.bak.bak +0 -157
- janito/termweb/static/termweb_quickopen.js +0 -135
- janito/termweb/static/termweb_quickopen.js.bak +0 -125
- janito/tests/test_rich_utils.py +0 -44
- janito/web/__init__.py +0 -0
- janito/web/__main__.py +0 -25
- janito/web/app.py +0 -145
- janito-1.14.3.dist-info/METADATA +0 -313
- janito-1.14.3.dist-info/RECORD +0 -162
- janito-1.14.3.dist-info/licenses/LICENSE +0 -21
- /janito/{shell → cli/chat_mode/shell}/input_history.py +0 -0
- /janito/{shell/commands/session.py → cli/chat_mode/shell/session/history.py} +0 -0
- /janito/{agent/tools_utils/formatting.py → formatting.py} +0 -0
- /janito/{agent/tools_utils/gitignore_utils.py → gitignore_utils.py} +0 -0
- /janito/{agent/platform_discovery.py → platform_discovery.py} +0 -0
- /janito/{agent/tools → tools/adapters/local}/get_file_outline/__init__.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/get_file_outline/markdown_outline.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/search_text/__init__.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/validate_file_syntax/__init__.py +0 -0
- {janito-1.14.3.dist-info → janito-2.0.0.dist-info}/WHEEL +0 -0
- {janito-1.14.3.dist-info → janito-2.0.0.dist-info}/entry_points.txt +0 -0
- {janito-1.14.3.dist-info → janito-2.0.0.dist-info}/top_level.txt +0 -0
janito/cli/config.py
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
from janito.config import config
|
2
|
+
|
3
|
+
CONFIG_OPTIONS = {
|
4
|
+
"api_key": "API key for OpenAI-compatible service (required)", # pragma: allowlist secret
|
5
|
+
"trust": "Trust mode: suppress all console output (bool, default: False)",
|
6
|
+
"model": "Model name to use (e.g., 'gpt-4.1', 'gpt-4o', 'gpt-4-turbo', 'o3-mini', 'o4-mini', 'o4-mini-high')",
|
7
|
+
"base_url": "API base URL (OpenAI-compatible endpoint)",
|
8
|
+
"role": "Role description for the Agent Profile (e.g., 'software engineer')",
|
9
|
+
"temperature": "Sampling temperature (float, e.g., 0.0 - 2.0)",
|
10
|
+
"max_tokens": "Maximum tokens for model response (int)",
|
11
|
+
"use_azure_openai": "Whether to use Azure OpenAI client (default: False)",
|
12
|
+
"template": "Template context dictionary for Agent Profile prompt rendering (nested)",
|
13
|
+
"profile": "Agent Profile name (only 'base' is supported)",
|
14
|
+
}
|
15
|
+
|
16
|
+
DEFAULT_TERMWEB_PORT = 8088
|
17
|
+
|
18
|
+
|
19
|
+
def get_termweb_port():
|
20
|
+
port = config.get("termweb_port")
|
21
|
+
try:
|
22
|
+
return int(port)
|
23
|
+
except Exception:
|
24
|
+
return DEFAULT_TERMWEB_PORT
|
25
|
+
|
26
|
+
|
27
|
+
def set_termweb_port(port):
|
28
|
+
config.file_set("termweb_port", int(port))
|
janito/cli/console.py
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
"""Stub implementation of EventLogger for the CLI event logging system."""
|
2
|
+
|
3
|
+
|
4
|
+
class EventLogger:
|
5
|
+
def __init__(self, debug=False):
|
6
|
+
self.debug = debug
|
7
|
+
|
8
|
+
def subscribe(self, event_name, callback):
|
9
|
+
if self.debug:
|
10
|
+
pass # Add debug subscribe output if needed
|
11
|
+
# No real subscription logic
|
12
|
+
|
13
|
+
def submit(self, event_name, payload=None):
|
14
|
+
if self.debug:
|
15
|
+
pass # Add debug submit output if needed
|
16
|
+
# No real submission logic
|
17
|
+
|
18
|
+
|
19
|
+
def setup_event_logger(args):
|
20
|
+
debug = getattr(args, "event_debug", False)
|
21
|
+
event_logger = EventLogger(debug=debug)
|
22
|
+
print("[EventLog] Event logger is now active (stub implementation)")
|
23
|
+
return event_logger
|
24
|
+
|
25
|
+
|
26
|
+
def setup_event_logger_if_needed(args):
|
27
|
+
if getattr(args, "event_log", False):
|
28
|
+
print("[EventLog] Setting up event logger with system bus...")
|
29
|
+
event_logger = setup_event_logger(args)
|
30
|
+
from janito.event_bus import event_bus
|
31
|
+
|
32
|
+
def event_logger_handler(event):
|
33
|
+
from janito.cli.console import shared_console
|
34
|
+
from rich.pretty import Pretty
|
35
|
+
from datetime import datetime
|
36
|
+
|
37
|
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
38
|
+
shared_console.print(
|
39
|
+
f"[EventLog] [dim]{timestamp}[/] [bold green]{event.__class__.__name__}[/] | [cyan]{getattr(event, 'category', '')}[/]"
|
40
|
+
)
|
41
|
+
shared_console.print(Pretty(event, expand_all=True))
|
42
|
+
shared_console.file.flush()
|
43
|
+
|
44
|
+
from janito.event_bus.event import Event
|
45
|
+
|
46
|
+
event_bus.subscribe(Event, event_logger_handler)
|
47
|
+
|
48
|
+
|
49
|
+
def inject_debug_event_bus_if_needed(args):
|
50
|
+
if getattr(args, "event_debug", False):
|
51
|
+
from janito.event_bus import event_bus
|
52
|
+
|
53
|
+
orig_publish = event_bus.publish
|
54
|
+
|
55
|
+
def debug_publish(event):
|
56
|
+
# You can enrich here if needed
|
57
|
+
return orig_publish(event)
|
58
|
+
|
59
|
+
event_bus.publish = debug_publish
|
@@ -0,0 +1,31 @@
|
|
1
|
+
"""Handlers for get-type CLI commands (show_config, list_providers, models, tools)."""
|
2
|
+
|
3
|
+
from janito.cli.cli_commands.list_providers import handle_list_providers
|
4
|
+
from janito.cli.cli_commands.list_models import handle_list_models
|
5
|
+
from janito.cli.cli_commands.list_tools import handle_list_tools
|
6
|
+
from janito.cli.cli_commands.show_config import handle_show_config
|
7
|
+
from functools import partial
|
8
|
+
from janito.provider_registry import ProviderRegistry
|
9
|
+
|
10
|
+
GETTER_KEYS = ["show_config", "list_providers", "list_models", "list_tools"]
|
11
|
+
|
12
|
+
|
13
|
+
def handle_getter(args, config_mgr=None):
|
14
|
+
provider_instance = None
|
15
|
+
if getattr(args, "list_models", False):
|
16
|
+
provider = getattr(args, "provider", None)
|
17
|
+
if not provider:
|
18
|
+
print(
|
19
|
+
"Error: No provider selected. Please set a provider using '-p PROVIDER', '--set provider=name', or configure a provider."
|
20
|
+
)
|
21
|
+
return
|
22
|
+
provider_instance = ProviderRegistry().get_instance(provider)
|
23
|
+
GETTER_DISPATCH = {
|
24
|
+
"list_providers": partial(handle_list_providers, args),
|
25
|
+
"list_models": partial(handle_list_models, args, provider_instance),
|
26
|
+
"list_tools": partial(handle_list_tools, args),
|
27
|
+
"show_config": partial(handle_show_config, args),
|
28
|
+
}
|
29
|
+
for arg in GETTER_KEYS:
|
30
|
+
if getattr(args, arg, False) and arg in GETTER_DISPATCH:
|
31
|
+
return GETTER_DISPATCH[arg]()
|
@@ -0,0 +1,141 @@
|
|
1
|
+
"""Handles LLM driver config preparation and execution modes."""
|
2
|
+
|
3
|
+
from janito.llm.driver_config import LLMDriverConfig
|
4
|
+
from janito.provider_config import get_config_provider
|
5
|
+
from janito.cli.verbose_output import print_verbose_info
|
6
|
+
|
7
|
+
|
8
|
+
def _choose_provider(args):
|
9
|
+
provider = getattr(args, "provider", None)
|
10
|
+
if provider is None:
|
11
|
+
provider = get_config_provider()
|
12
|
+
if provider and getattr(args, "verbose", False):
|
13
|
+
print_verbose_info(
|
14
|
+
"Default provider", provider, style="magenta", align_content=True
|
15
|
+
)
|
16
|
+
elif provider is None:
|
17
|
+
print(
|
18
|
+
"Error: No provider selected and no provider found in config. Please set a provider using '-p PROVIDER', '--set provider=name', or configure a provider."
|
19
|
+
)
|
20
|
+
return None
|
21
|
+
return provider
|
22
|
+
|
23
|
+
|
24
|
+
def _populate_driver_config_data(args, modifiers, provider, model):
|
25
|
+
from janito.provider_config import get_effective_setting
|
26
|
+
|
27
|
+
CONFIG_LOOKUP_KEYS = ("max_tokens", "base_url")
|
28
|
+
driver_config_data = {"model": model}
|
29
|
+
if getattr(args, "verbose_api", None) is not None:
|
30
|
+
driver_config_data["verbose_api"] = args.verbose_api
|
31
|
+
for field in LLMDriverConfig.__dataclass_fields__:
|
32
|
+
if field in CONFIG_LOOKUP_KEYS:
|
33
|
+
if field in modifiers and modifiers[field] is not None:
|
34
|
+
driver_config_data[field] = modifiers[field]
|
35
|
+
else:
|
36
|
+
value = get_effective_setting(provider, model, field)
|
37
|
+
if value is not None:
|
38
|
+
driver_config_data[field] = value
|
39
|
+
elif field in modifiers and field != "model":
|
40
|
+
driver_config_data[field] = modifiers[field]
|
41
|
+
return driver_config_data
|
42
|
+
|
43
|
+
|
44
|
+
def prepare_llm_driver_config(args, modifiers):
|
45
|
+
"""Prepare the LLMDriverConfig instance based on CLI *args* and *modifiers*.
|
46
|
+
|
47
|
+
This helper additionally validates that the chosen ``--model`` (or the
|
48
|
+
resolved model coming from config precedence) is actually available for the
|
49
|
+
selected provider. If the combination is invalid an error is printed and
|
50
|
+
``None`` is returned for the config so that the caller can abort execution
|
51
|
+
gracefully.
|
52
|
+
"""
|
53
|
+
provider = _choose_provider(args)
|
54
|
+
if provider is None:
|
55
|
+
return None, None, None
|
56
|
+
from janito.provider_config import get_effective_model
|
57
|
+
|
58
|
+
model = getattr(args, "model", None)
|
59
|
+
if not model:
|
60
|
+
model = get_effective_model(provider)
|
61
|
+
|
62
|
+
# Validate that the chosen model is supported by the selected provider
|
63
|
+
if model:
|
64
|
+
from janito.provider_registry import ProviderRegistry
|
65
|
+
|
66
|
+
provider_instance = None
|
67
|
+
try:
|
68
|
+
provider_instance = ProviderRegistry().get_instance(provider)
|
69
|
+
available_models = [
|
70
|
+
m["name"]
|
71
|
+
for m in provider_instance.get_model_info().values()
|
72
|
+
if isinstance(m, dict) and "name" in m
|
73
|
+
]
|
74
|
+
if model not in available_models:
|
75
|
+
print(
|
76
|
+
f"Error: Model '{model}' is not available for provider '{provider}'."
|
77
|
+
)
|
78
|
+
print(f"Available models: {', '.join(available_models)}")
|
79
|
+
return provider, None, None
|
80
|
+
except Exception as e:
|
81
|
+
print(f"Error validating model for provider '{provider}': {e}")
|
82
|
+
return provider, None, None
|
83
|
+
driver_config_data = _populate_driver_config_data(args, modifiers, provider, model)
|
84
|
+
llm_driver_config = LLMDriverConfig(**driver_config_data)
|
85
|
+
if getattr(llm_driver_config, "verbose_api", None):
|
86
|
+
pass
|
87
|
+
agent_role = modifiers.get("role", "software developer")
|
88
|
+
return provider, llm_driver_config, agent_role
|
89
|
+
|
90
|
+
|
91
|
+
def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=False, exec_enabled=False):
|
92
|
+
"""
|
93
|
+
Main runner for CLI execution. If exec_enabled is False, disables execution/run tools.
|
94
|
+
"""
|
95
|
+
zero_mode = getattr(args, "zero", False)
|
96
|
+
from janito.provider_registry import ProviderRegistry
|
97
|
+
|
98
|
+
# Patch: disable execution/run tools if not enabled
|
99
|
+
if not exec_enabled:
|
100
|
+
import janito.tools
|
101
|
+
adapter = janito.tools.get_local_tools_adapter()
|
102
|
+
if hasattr(adapter, "disable_execution_tools"):
|
103
|
+
adapter.disable_execution_tools()
|
104
|
+
else:
|
105
|
+
pass
|
106
|
+
|
107
|
+
provider_instance = ProviderRegistry().get_instance(provider, llm_driver_config)
|
108
|
+
mode = get_prompt_mode(args)
|
109
|
+
if getattr(args, "verbose", False):
|
110
|
+
print_verbose_info(
|
111
|
+
"Active LLMDriverConfig (after provider)", llm_driver_config, style="green"
|
112
|
+
)
|
113
|
+
print_verbose_info("Agent role", agent_role, style="green")
|
114
|
+
if mode == "single_shot":
|
115
|
+
from janito.cli.single_shot_mode.handler import (
|
116
|
+
PromptHandler as SingleShotPromptHandler,
|
117
|
+
)
|
118
|
+
|
119
|
+
handler = SingleShotPromptHandler(
|
120
|
+
args, provider_instance, llm_driver_config, role=agent_role
|
121
|
+
)
|
122
|
+
handler.handle()
|
123
|
+
else:
|
124
|
+
from janito.cli.chat_mode.session import ChatSession
|
125
|
+
from rich.console import Console
|
126
|
+
|
127
|
+
console = Console()
|
128
|
+
session = ChatSession(
|
129
|
+
console,
|
130
|
+
provider_instance,
|
131
|
+
llm_driver_config,
|
132
|
+
role=agent_role,
|
133
|
+
args=args,
|
134
|
+
verbose_tools=verbose_tools,
|
135
|
+
verbose_agent=getattr(args, "verbose_agent", False),
|
136
|
+
)
|
137
|
+
session.run()
|
138
|
+
|
139
|
+
|
140
|
+
def get_prompt_mode(args):
|
141
|
+
return "single_shot" if getattr(args, "user_prompt", None) else "chat_mode"
|
@@ -0,0 +1,174 @@
|
|
1
|
+
"""Handlers for set-type CLI commands (provider, model, api keys, etc)."""
|
2
|
+
|
3
|
+
from janito.provider_config import set_config_provider
|
4
|
+
from janito.config import config as global_config
|
5
|
+
from janito.provider_registry import ProviderRegistry
|
6
|
+
from janito.cli.cli_commands.set_api_key import handle_set_api_key
|
7
|
+
|
8
|
+
|
9
|
+
def handle_api_key_set(args):
|
10
|
+
if getattr(args, "set_api_key", None):
|
11
|
+
handle_set_api_key(args)
|
12
|
+
return True
|
13
|
+
return False
|
14
|
+
|
15
|
+
|
16
|
+
def handle_set(args, config_mgr=None):
|
17
|
+
set_arg = getattr(args, "set", None)
|
18
|
+
if not set_arg:
|
19
|
+
return False
|
20
|
+
try:
|
21
|
+
if "=" not in set_arg:
|
22
|
+
print(
|
23
|
+
"Error: --set requires KEY=VALUE (e.g., --set provider=provider_name)."
|
24
|
+
)
|
25
|
+
return True
|
26
|
+
key, value = set_arg.split("=", 1)
|
27
|
+
key, value = key.strip(), value.strip()
|
28
|
+
key = key.replace("-", "_")
|
29
|
+
|
30
|
+
if key == "provider":
|
31
|
+
return _handle_set_config_provider(value)
|
32
|
+
if key == "model":
|
33
|
+
return _handle_set_global_model(value)
|
34
|
+
if "." in key and key.endswith(".model"):
|
35
|
+
return _handle_set_provider_model(key, value)
|
36
|
+
if key == "max_tokens":
|
37
|
+
return _handle_set_max_tokens(value)
|
38
|
+
if key == "base_url":
|
39
|
+
return _handle_set_base_url(value)
|
40
|
+
if ".max_tokens" in key or ".base_url" in key:
|
41
|
+
return _handle_set_provider_level_setting(key, value)
|
42
|
+
print(
|
43
|
+
f"Error: Unknown config key '{key}'. Supported: provider, model, <provider>.model, max_tokens, base_url, <provider>.max_tokens, <provider>.base_url, <provider>.<model>.max_tokens, <provider>.<model>.base_url"
|
44
|
+
)
|
45
|
+
return True
|
46
|
+
except Exception as e:
|
47
|
+
print(f"Error parsing --set value: {e}")
|
48
|
+
return True
|
49
|
+
|
50
|
+
|
51
|
+
def _handle_set_max_tokens(value):
|
52
|
+
try:
|
53
|
+
ival = int(value)
|
54
|
+
except Exception:
|
55
|
+
print("Error: max_tokens must be set to an integer value.")
|
56
|
+
return True
|
57
|
+
global_config.file_set("max_tokens", ival)
|
58
|
+
print(f"Top-level max_tokens set to {ival}.")
|
59
|
+
return True
|
60
|
+
|
61
|
+
|
62
|
+
def _handle_set_base_url(value):
|
63
|
+
global_config.file_set("base_url", value)
|
64
|
+
print(f"Top-level base_url set to {value}.")
|
65
|
+
return True
|
66
|
+
|
67
|
+
|
68
|
+
def _handle_set_provider_level_setting(key, value):
|
69
|
+
parts = key.split(".")
|
70
|
+
if len(parts) == 2:
|
71
|
+
provider, par_key = parts
|
72
|
+
if par_key == "max_tokens":
|
73
|
+
try:
|
74
|
+
ival = int(value)
|
75
|
+
except Exception:
|
76
|
+
print("Error: max_tokens must be set to an integer value.")
|
77
|
+
return True
|
78
|
+
global_config.set_provider_config(provider, "max_tokens", ival)
|
79
|
+
print(f"max_tokens for provider '{provider}' set to {ival}.")
|
80
|
+
return True
|
81
|
+
if par_key == "base_url":
|
82
|
+
global_config.set_provider_config(provider, "base_url", value)
|
83
|
+
print(f"base_url for provider '{provider}' set to {value}.")
|
84
|
+
return True
|
85
|
+
elif len(parts) == 3:
|
86
|
+
provider, model, mk = parts
|
87
|
+
if mk == "max_tokens":
|
88
|
+
try:
|
89
|
+
ival = int(value)
|
90
|
+
except Exception:
|
91
|
+
print("Error: max_tokens must be set to an integer value.")
|
92
|
+
return True
|
93
|
+
global_config.set_provider_model_config(provider, model, "max_tokens", ival)
|
94
|
+
print(
|
95
|
+
f"max_tokens for provider '{provider}', model '{model}' set to {ival}."
|
96
|
+
)
|
97
|
+
return True
|
98
|
+
if mk == "base_url":
|
99
|
+
global_config.set_provider_model_config(provider, model, "base_url", value)
|
100
|
+
print(
|
101
|
+
f"base_url for provider '{provider}', model '{model}' set to {value}."
|
102
|
+
)
|
103
|
+
return True
|
104
|
+
print(
|
105
|
+
f"Error: Unknown config key '{key}'. Supported: provider, model, <provider>.model, max_tokens, base_url, <provider>.max_tokens, <provider>.base_url, <provider>.<model>.max_tokens, <provider>.<model>.base_url"
|
106
|
+
)
|
107
|
+
return True
|
108
|
+
|
109
|
+
|
110
|
+
def _handle_set_config_provider(value):
|
111
|
+
try:
|
112
|
+
supported = ProviderRegistry().get_provider(value)
|
113
|
+
except Exception:
|
114
|
+
print(
|
115
|
+
f"Error: Provider '{value}' is not supported. Run '--list-providers' to see the supported list."
|
116
|
+
)
|
117
|
+
return True
|
118
|
+
from janito.provider_config import set_config_provider
|
119
|
+
|
120
|
+
set_config_provider(value)
|
121
|
+
print(f"Provider set to '{value}'.")
|
122
|
+
return True
|
123
|
+
|
124
|
+
|
125
|
+
def _handle_set_provider_model(key, value):
|
126
|
+
provider_name, suffix = key.rsplit(".", 1)
|
127
|
+
if suffix != "model":
|
128
|
+
print(
|
129
|
+
f"Error: Only <provider>.model is supported for provider-specific model override. Not: '{key}'"
|
130
|
+
)
|
131
|
+
return True
|
132
|
+
try:
|
133
|
+
provider_cls = ProviderRegistry().get_provider(provider_name)
|
134
|
+
provider_instance = provider_cls()
|
135
|
+
except Exception:
|
136
|
+
print(
|
137
|
+
f"Error: Provider '{provider_name}' is not supported. Run '--list-providers' to see the supported list."
|
138
|
+
)
|
139
|
+
return True
|
140
|
+
model_info = provider_instance.get_model_info(value)
|
141
|
+
if not model_info:
|
142
|
+
print(
|
143
|
+
f"Error: Model '{value}' is not defined for provider '{provider_name}'. Run '-p {provider_name} -l' to see models."
|
144
|
+
)
|
145
|
+
return True
|
146
|
+
global_config.set_provider_config(provider_name, "model", value)
|
147
|
+
print(f"Default model for provider '{provider_name}' set to '{value}'.")
|
148
|
+
return True
|
149
|
+
|
150
|
+
|
151
|
+
def _handle_set_global_model(value):
|
152
|
+
# Try to validate model choice (against current provider if possible)
|
153
|
+
provider_name = global_config.get("provider")
|
154
|
+
if provider_name:
|
155
|
+
try:
|
156
|
+
provider_cls = ProviderRegistry().get_provider(provider_name)
|
157
|
+
provider_instance = provider_cls()
|
158
|
+
model_info = provider_instance.get_model_info(value)
|
159
|
+
if not model_info:
|
160
|
+
print(
|
161
|
+
f"Error: Model '{value}' is not defined for provider '{provider_name}'. Run '-p {provider_name} -l' to see models."
|
162
|
+
)
|
163
|
+
return True
|
164
|
+
except Exception:
|
165
|
+
print(
|
166
|
+
f"Warning: Could not validate model for provider '{provider_name}'. Setting anyway."
|
167
|
+
)
|
168
|
+
else:
|
169
|
+
print(
|
170
|
+
"Warning: No provider set. Model will be set globally, but may not be valid for any provider."
|
171
|
+
)
|
172
|
+
global_config.file_set("model", value)
|
173
|
+
print(f"Global default model set to '{value}'.")
|
174
|
+
return True
|
@@ -0,0 +1,54 @@
|
|
1
|
+
from janito.config import config as global_config
|
2
|
+
|
3
|
+
|
4
|
+
def handle_unset(args):
|
5
|
+
unset_arg = getattr(args, "unset", None)
|
6
|
+
if not unset_arg:
|
7
|
+
return False
|
8
|
+
key = unset_arg.strip().replace("-", "_")
|
9
|
+
if "." in key:
|
10
|
+
# Provider or model-specific keys
|
11
|
+
parts = key.split(".")
|
12
|
+
if len(parts) == 2:
|
13
|
+
provider, subkey = parts
|
14
|
+
current_val = (
|
15
|
+
global_config.file_config.get("providers", {})
|
16
|
+
.get(provider, {})
|
17
|
+
.get(subkey)
|
18
|
+
)
|
19
|
+
if current_val is not None:
|
20
|
+
del global_config.file_config["providers"][provider][subkey]
|
21
|
+
global_config.save()
|
22
|
+
print(f"{key}={current_val} was removed.")
|
23
|
+
return True
|
24
|
+
elif len(parts) == 3:
|
25
|
+
provider, model, subkey = parts
|
26
|
+
model_conf = (
|
27
|
+
global_config.file_config.get("providers", {})
|
28
|
+
.get(provider, {})
|
29
|
+
.get("models", {})
|
30
|
+
.get(model, {})
|
31
|
+
)
|
32
|
+
current_val = model_conf.get(subkey)
|
33
|
+
if current_val is not None:
|
34
|
+
del global_config.file_config["providers"][provider]["models"][model][
|
35
|
+
subkey
|
36
|
+
]
|
37
|
+
global_config.save()
|
38
|
+
print(f"{key}={current_val} was removed.")
|
39
|
+
return True
|
40
|
+
else:
|
41
|
+
current_val = global_config.file_config.get(key)
|
42
|
+
if current_val is not None:
|
43
|
+
del global_config.file_config[key]
|
44
|
+
global_config.save()
|
45
|
+
print(f"{key}={current_val} was removed.")
|
46
|
+
return True
|
47
|
+
if "=" in unset_arg:
|
48
|
+
provided_key = unset_arg.split("=")[0].strip()
|
49
|
+
print(
|
50
|
+
f"Error: --unset expected a key, not key=value. Did you mean: --unset {provided_key}?"
|
51
|
+
)
|
52
|
+
else:
|
53
|
+
print(f"Error: no value set for {key} (cannot remove)")
|
54
|
+
return True
|