janito 2.2.0__py3-none-any.whl → 2.3.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/__init__.py +1 -1
- janito/agent/setup_agent.py +14 -5
- janito/agent/templates/profiles/system_prompt_template_main.txt.j2 +3 -1
- janito/cli/chat_mode/bindings.py +6 -0
- janito/cli/chat_mode/session.py +16 -0
- janito/cli/chat_mode/shell/commands/__init__.py +3 -0
- janito/cli/chat_mode/shell/commands/exec.py +27 -0
- janito/cli/chat_mode/shell/commands/tools.py +17 -6
- janito/cli/chat_mode/shell/session/manager.py +1 -0
- janito/cli/chat_mode/toolbar.py +1 -0
- janito/cli/cli_commands/model_utils.py +95 -84
- janito/cli/config.py +2 -1
- janito/cli/core/getters.py +33 -31
- janito/cli/core/runner.py +165 -148
- janito/cli/core/setters.py +5 -1
- janito/cli/main_cli.py +12 -1
- janito/cli/prompt_core.py +5 -2
- janito/cli/rich_terminal_reporter.py +22 -3
- janito/cli/single_shot_mode/handler.py +11 -1
- janito/cli/verbose_output.py +1 -1
- janito/config_manager.py +112 -110
- janito/driver_events.py +14 -0
- janito/drivers/azure_openai/driver.py +38 -3
- janito/drivers/driver_registry.py +0 -2
- janito/drivers/openai/driver.py +196 -36
- janito/llm/auth.py +63 -62
- janito/llm/driver.py +7 -1
- janito/llm/driver_config.py +1 -0
- janito/provider_config.py +7 -3
- janito/provider_registry.py +18 -0
- janito/providers/__init__.py +1 -0
- janito/providers/anthropic/provider.py +4 -2
- janito/providers/azure_openai/model_info.py +16 -15
- janito/providers/azure_openai/provider.py +33 -2
- janito/providers/deepseek/provider.py +3 -0
- janito/providers/google/model_info.py +21 -29
- janito/providers/google/provider.py +52 -38
- janito/providers/mistralai/provider.py +5 -2
- janito/providers/openai/provider.py +4 -0
- janito/providers/provider_static_info.py +2 -3
- janito/tools/adapters/local/adapter.py +33 -11
- janito/tools/adapters/local/delete_text_in_file.py +4 -7
- janito/tools/adapters/local/move_file.py +3 -13
- janito/tools/adapters/local/remove_directory.py +6 -17
- janito/tools/adapters/local/remove_file.py +4 -10
- janito/tools/adapters/local/replace_text_in_file.py +6 -9
- janito/tools/adapters/local/search_text/match_lines.py +1 -1
- janito/tools/tools_adapter.py +78 -6
- janito/version.py +1 -1
- {janito-2.2.0.dist-info → janito-2.3.1.dist-info}/METADATA +149 -10
- {janito-2.2.0.dist-info → janito-2.3.1.dist-info}/RECORD +55 -56
- janito/drivers/google_genai/driver.py +0 -54
- janito/drivers/google_genai/schema_generator.py +0 -67
- {janito-2.2.0.dist-info → janito-2.3.1.dist-info}/WHEEL +0 -0
- {janito-2.2.0.dist-info → janito-2.3.1.dist-info}/entry_points.txt +0 -0
- {janito-2.2.0.dist-info → janito-2.3.1.dist-info}/licenses/LICENSE +0 -0
- {janito-2.2.0.dist-info → janito-2.3.1.dist-info}/top_level.txt +0 -0
janito/__init__.py
CHANGED
janito/agent/setup_agent.py
CHANGED
@@ -20,6 +20,7 @@ def setup_agent(
|
|
20
20
|
output_queue=None,
|
21
21
|
verbose_tools=False,
|
22
22
|
verbose_agent=False,
|
23
|
+
exec_enabled=False,
|
23
24
|
):
|
24
25
|
"""
|
25
26
|
Creates an agent using a rendered system prompt template, passing an explicit role.
|
@@ -62,17 +63,23 @@ def setup_agent(
|
|
62
63
|
f"Template file not found in either {template_path} or package resource."
|
63
64
|
)
|
64
65
|
|
66
|
+
import time
|
65
67
|
template = Template(template_content)
|
66
68
|
# Prepare context for Jinja2 rendering from llm_driver_config
|
67
69
|
# Compose context for Jinja2 rendering without using to_dict or temperature
|
68
70
|
context = {}
|
69
71
|
context["role"] = role or "software developer"
|
70
|
-
# Inject current platform environment information
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
# Inject current platform environment information only if exec_enabled
|
73
|
+
context["exec_enabled"] = bool(exec_enabled)
|
74
|
+
if exec_enabled:
|
75
|
+
pd = PlatformDiscovery()
|
76
|
+
context["platform"] = pd.get_platform_name()
|
77
|
+
context["python_version"] = pd.get_python_version()
|
78
|
+
context["shell_info"] = pd.detect_shell()
|
79
|
+
start_render = time.time()
|
75
80
|
rendered_prompt = template.render(**context)
|
81
|
+
end_render = time.time()
|
82
|
+
|
76
83
|
# Create the agent as before, now passing the explicit role
|
77
84
|
# Do NOT pass temperature; do not depend on to_dict
|
78
85
|
agent = LLMAgent(
|
@@ -97,6 +104,7 @@ def create_configured_agent(
|
|
97
104
|
verbose_agent=False,
|
98
105
|
templates_dir=None,
|
99
106
|
zero_mode=False,
|
107
|
+
exec_enabled=False,
|
100
108
|
):
|
101
109
|
"""
|
102
110
|
Normalizes agent setup for all CLI modes.
|
@@ -133,6 +141,7 @@ def create_configured_agent(
|
|
133
141
|
output_queue=output_queue,
|
134
142
|
verbose_tools=verbose_tools,
|
135
143
|
verbose_agent=verbose_agent,
|
144
|
+
exec_enabled=exec_enabled,
|
136
145
|
)
|
137
146
|
if driver is not None:
|
138
147
|
agent.driver = driver # Attach driver to agent for thread management
|
@@ -6,11 +6,13 @@ You are: {{ role }}
|
|
6
6
|
You will answer following a pattern of: discovery, description, implementation (when a change is requested) and validation.
|
7
7
|
|
8
8
|
{# Improves tool selection and platform specific constrains, eg, path format, C:\ vs /path #}
|
9
|
+
{% if exec_enabled %}
|
9
10
|
You will be using the following environment:
|
10
11
|
Platform: {{ platform }}
|
11
12
|
Python version: {{ python_version }}
|
12
13
|
Shell/Environment: {{ shell_info }}
|
13
|
-
|
14
|
+
{% endif %}
|
15
|
+
|
14
16
|
Before answering map the questions to artifacts found in the current directory - the current project.
|
15
17
|
|
16
18
|
Respond according to the following guidelines:
|
janito/cli/chat_mode/bindings.py
CHANGED
@@ -28,6 +28,12 @@ class KeyBindingsFactory:
|
|
28
28
|
buf.text = "/restart"
|
29
29
|
buf.validate_and_handle()
|
30
30
|
|
31
|
+
@bindings.add("f2")
|
32
|
+
def _(event):
|
33
|
+
buf = event.app.current_buffer
|
34
|
+
buf.text = "/exec on"
|
35
|
+
buf.validate_and_handle()
|
36
|
+
|
31
37
|
@bindings.add("f12")
|
32
38
|
def _(event):
|
33
39
|
buf = event.app.current_buffer
|
janito/cli/chat_mode/session.py
CHANGED
@@ -20,6 +20,7 @@ from janito.cli.chat_mode.shell.autocomplete import ShellCommandCompleter
|
|
20
20
|
|
21
21
|
class ChatShellState:
|
22
22
|
def __init__(self, mem_history, conversation_history):
|
23
|
+
self.allow_execution = False # Controls whether execution tools are enabled
|
23
24
|
self.mem_history = mem_history
|
24
25
|
self.conversation_history = conversation_history
|
25
26
|
self.paste_mode = False
|
@@ -52,7 +53,13 @@ class ChatSession:
|
|
52
53
|
args=None,
|
53
54
|
verbose_tools=False,
|
54
55
|
verbose_agent=False,
|
56
|
+
exec_enabled=False
|
55
57
|
):
|
58
|
+
# Set allow_execution from exec_enabled or args
|
59
|
+
if args is not None and hasattr(args, "exec"):
|
60
|
+
allow_execution = bool(getattr(args, "exec", False))
|
61
|
+
else:
|
62
|
+
allow_execution = exec_enabled
|
56
63
|
from janito.cli.prompt_core import PromptHandler as GenericPromptHandler
|
57
64
|
|
58
65
|
self._prompt_handler = GenericPromptHandler(
|
@@ -82,12 +89,21 @@ class ChatSession:
|
|
82
89
|
role=role,
|
83
90
|
verbose_tools=verbose_tools,
|
84
91
|
verbose_agent=verbose_agent,
|
92
|
+
exec_enabled=allow_execution
|
85
93
|
)
|
86
94
|
from janito.conversation_history import LLMConversationHistory
|
87
95
|
|
88
96
|
self.shell_state = ChatShellState(self.mem_history, LLMConversationHistory())
|
89
97
|
self.shell_state.agent = agent
|
98
|
+
self.shell_state.allow_execution = allow_execution
|
90
99
|
self.agent = agent
|
100
|
+
# Filter execution tools at startup
|
101
|
+
try:
|
102
|
+
registry = getattr(__import__('janito.tools', fromlist=['get_local_tools_adapter']), 'get_local_tools_adapter')()
|
103
|
+
if hasattr(registry, 'set_execution_tools_enabled'):
|
104
|
+
registry.set_execution_tools_enabled(allow_execution)
|
105
|
+
except Exception as e:
|
106
|
+
self.console.print(f"[yellow]Warning: Could not filter execution tools at startup: {e}[/yellow]")
|
91
107
|
from janito.perf_singleton import performance_collector
|
92
108
|
|
93
109
|
self.performance_collector = performance_collector
|
@@ -13,6 +13,9 @@ from .help import HelpShellHandler
|
|
13
13
|
from janito.cli.console import shared_console
|
14
14
|
|
15
15
|
COMMAND_HANDLERS = {
|
16
|
+
"/exec": __import__(
|
17
|
+
"janito.cli.chat_mode.shell.commands.exec", fromlist=["ExecShellHandler"]
|
18
|
+
).ExecShellHandler,
|
16
19
|
"/clear": __import__(
|
17
20
|
"janito.cli.chat_mode.shell.commands.clear", fromlist=["ClearShellHandler"]
|
18
21
|
).ClearShellHandler,
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from janito.cli.console import shared_console
|
2
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
3
|
+
|
4
|
+
class ExecShellHandler(ShellCmdHandler):
|
5
|
+
help_text = "/exec on|off: Enable or disable code and command execution tools. Usage: /exec on or /exec off."
|
6
|
+
|
7
|
+
def run(self):
|
8
|
+
if not self.shell_state:
|
9
|
+
shared_console.print("[red]Shell state unavailable.[/red]")
|
10
|
+
return
|
11
|
+
arg = (self.after_cmd_line or "").strip().lower()
|
12
|
+
if arg not in ("on", "off"):
|
13
|
+
shared_console.print("[yellow]Usage: /exec on|off[/yellow]")
|
14
|
+
return
|
15
|
+
enable = arg == "on"
|
16
|
+
self.shell_state.allow_execution = enable
|
17
|
+
# Dynamically enable/disable execution tools in the registry
|
18
|
+
try:
|
19
|
+
registry = __import__('janito.tools', fromlist=['get_local_tools_adapter']).get_local_tools_adapter()
|
20
|
+
if hasattr(registry, 'set_execution_tools_enabled'):
|
21
|
+
registry.set_execution_tools_enabled(enable)
|
22
|
+
except Exception as e:
|
23
|
+
shared_console.print(f"[yellow]Warning: Could not update execution tools dynamically: {e}[/yellow]")
|
24
|
+
if enable:
|
25
|
+
shared_console.print("[green]Execution tools ENABLED. You can now use code and command execution tools.[/green]")
|
26
|
+
else:
|
27
|
+
shared_console.print("[yellow]Execution tools DISABLED. Code and command execution tools are now blocked.[/yellow]")
|
@@ -6,18 +6,29 @@ class ToolsShellHandler(ShellCmdHandler):
|
|
6
6
|
|
7
7
|
def run(self):
|
8
8
|
try:
|
9
|
+
# Initialize allow_execution before use
|
10
|
+
allow_execution = False
|
11
|
+
if hasattr(self, 'shell_state') and self.shell_state is not None:
|
12
|
+
allow_execution = getattr(self.shell_state, 'allow_execution', False)
|
13
|
+
|
9
14
|
import janito.tools # Ensure all tools are registered
|
10
15
|
registry = janito.tools.get_local_tools_adapter()
|
11
16
|
tools = registry.list_tools()
|
12
17
|
shared_console.print("Registered tools:" if tools else "No tools registered.")
|
18
|
+
# Get tool instances for annotation
|
19
|
+
tool_instances = {t.tool_name: t for t in registry.get_tools()}
|
13
20
|
for tool in tools:
|
14
|
-
|
21
|
+
inst = tool_instances.get(tool, None)
|
22
|
+
is_exec = getattr(inst, 'provides_execution', False) if inst else False
|
23
|
+
if is_exec and not allow_execution:
|
24
|
+
shared_console.print(f"- {tool} (disabled)")
|
25
|
+
else:
|
26
|
+
shared_console.print(f"- {tool}")
|
15
27
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
allow_execution = getattr(self.shell_state, 'allow_execution', False)
|
28
|
+
if allow_execution:
|
29
|
+
shared_console.print("[green]Execution tools are ENABLED.[/green]")
|
30
|
+
else:
|
31
|
+
shared_console.print("[yellow]Execution tools are DISABLED. Use /exec on to enable them.[/yellow]")
|
21
32
|
|
22
33
|
# Find all possible execution tools (by convention: provides_execution = True)
|
23
34
|
exec_tools = []
|
@@ -95,6 +95,7 @@ def save_conversation(messages, prompts, usage_info=None, path=None):
|
|
95
95
|
|
96
96
|
with open(path, "w", encoding="utf-8") as f:
|
97
97
|
json.dump(data, f, indent=2, default=usage_serializer)
|
98
|
+
f.write("\n")
|
98
99
|
|
99
100
|
|
100
101
|
def last_conversation_exists(path=".janito/last_conversation.json"):
|
janito/cli/chat_mode/toolbar.py
CHANGED
@@ -24,6 +24,7 @@ def assemble_bindings_line(width):
|
|
24
24
|
return (
|
25
25
|
f" <key-label>CTRL-C</key-label>: Interrupt Request/Exit Shell | "
|
26
26
|
f"<key-label>F1</key-label>: Restart conversation | "
|
27
|
+
f"<key-label>F2</key-label>: Exec | "
|
27
28
|
f"<b>/help</b>: Help | "
|
28
29
|
f"<key-label>F12</key-label>: Do It "
|
29
30
|
)
|
@@ -1,84 +1,95 @@
|
|
1
|
-
"""
|
2
|
-
Utilities for model-related CLI output
|
3
|
-
"""
|
4
|
-
|
5
|
-
|
6
|
-
def _print_models_table(models, provider_name):
|
7
|
-
from rich.table import Table
|
8
|
-
from rich.console import Console
|
9
|
-
|
10
|
-
headers = [
|
11
|
-
"name",
|
12
|
-
"open",
|
13
|
-
"context",
|
14
|
-
"max_input",
|
15
|
-
"max_cot",
|
16
|
-
"max_response",
|
17
|
-
"thinking_supported",
|
18
|
-
"driver",
|
19
|
-
]
|
20
|
-
display_headers = [
|
21
|
-
"Model Name",
|
22
|
-
"Vendor",
|
23
|
-
"context",
|
24
|
-
"max_input",
|
25
|
-
"max_cot",
|
26
|
-
"max_response",
|
27
|
-
"Thinking",
|
28
|
-
"Driver",
|
29
|
-
]
|
30
|
-
table = Table(title=f"Supported models for provider '{provider_name}'")
|
31
|
-
_add_table_columns(table, display_headers)
|
32
|
-
num_fields = {"context", "max_input", "max_cot", "max_response"}
|
33
|
-
for m in models:
|
34
|
-
row = [str(m.get("name", ""))]
|
35
|
-
row.extend(_build_model_row(m, headers, num_fields))
|
36
|
-
table.add_row(*row)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
1
|
+
"""
|
2
|
+
Utilities for model-related CLI output
|
3
|
+
"""
|
4
|
+
|
5
|
+
|
6
|
+
def _print_models_table(models, provider_name):
|
7
|
+
from rich.table import Table
|
8
|
+
from rich.console import Console
|
9
|
+
|
10
|
+
headers = [
|
11
|
+
"name",
|
12
|
+
"open",
|
13
|
+
"context",
|
14
|
+
"max_input",
|
15
|
+
"max_cot",
|
16
|
+
"max_response",
|
17
|
+
"thinking_supported",
|
18
|
+
"driver",
|
19
|
+
]
|
20
|
+
display_headers = [
|
21
|
+
"Model Name",
|
22
|
+
"Vendor",
|
23
|
+
"context",
|
24
|
+
"max_input",
|
25
|
+
"max_cot",
|
26
|
+
"max_response",
|
27
|
+
"Thinking",
|
28
|
+
"Driver",
|
29
|
+
]
|
30
|
+
table = Table(title=f"Supported models for provider '{provider_name}'")
|
31
|
+
_add_table_columns(table, display_headers)
|
32
|
+
num_fields = {"context", "max_input", "max_cot", "max_response"}
|
33
|
+
for m in models:
|
34
|
+
row = [str(m.get("name", ""))]
|
35
|
+
row.extend(_build_model_row(m, headers, num_fields))
|
36
|
+
table.add_row(*row)
|
37
|
+
import sys
|
38
|
+
if sys.stdout.isatty():
|
39
|
+
from rich.console import Console
|
40
|
+
Console().print(table)
|
41
|
+
else:
|
42
|
+
# ASCII-friendly fallback table when output is redirected
|
43
|
+
print(f"Supported models for provider '{provider_name}'")
|
44
|
+
headers_fallback = [h for h in display_headers]
|
45
|
+
print(' | '.join(headers_fallback))
|
46
|
+
for m in models:
|
47
|
+
row = [str(m.get('name', ''))]
|
48
|
+
row.extend(_build_model_row(m, headers, num_fields))
|
49
|
+
print(' | '.join(row))
|
50
|
+
|
51
|
+
|
52
|
+
def _add_table_columns(table, display_headers):
|
53
|
+
for i, h in enumerate(display_headers):
|
54
|
+
justify = "right" if i == 0 else "center"
|
55
|
+
table.add_column(h, style="bold", justify=justify)
|
56
|
+
|
57
|
+
|
58
|
+
def _format_k(val):
|
59
|
+
try:
|
60
|
+
n = int(val)
|
61
|
+
if n >= 1000:
|
62
|
+
return f"{n // 1000}k"
|
63
|
+
return str(n)
|
64
|
+
except Exception:
|
65
|
+
return str(val)
|
66
|
+
|
67
|
+
|
68
|
+
def _build_model_row(m, headers, num_fields):
|
69
|
+
def format_driver(val):
|
70
|
+
if isinstance(val, (list, tuple)):
|
71
|
+
return ", ".join(val)
|
72
|
+
val_str = str(val)
|
73
|
+
return val_str.removesuffix("ModelDriver").strip()
|
74
|
+
|
75
|
+
row = []
|
76
|
+
for h in headers[1:]:
|
77
|
+
v = m.get(h, "")
|
78
|
+
if h in num_fields and v not in ("", "N/A"):
|
79
|
+
if (
|
80
|
+
h in ("context", "max_input")
|
81
|
+
and isinstance(v, (list, tuple))
|
82
|
+
and len(v) == 2
|
83
|
+
):
|
84
|
+
row.append(f"{_format_k(v[0])} / {_format_k(v[1])}")
|
85
|
+
else:
|
86
|
+
row.append(_format_k(v))
|
87
|
+
elif h == "open":
|
88
|
+
row.append("Open" if v is True or v == "Open" else "Locked")
|
89
|
+
elif h == "thinking_supported":
|
90
|
+
row.append("📖" if v is True or v == "True" else "")
|
91
|
+
elif h == "driver":
|
92
|
+
row.append(format_driver(v))
|
93
|
+
else:
|
94
|
+
row.append(str(v))
|
95
|
+
return row
|
janito/cli/config.py
CHANGED
@@ -3,8 +3,9 @@ from janito.config import config
|
|
3
3
|
CONFIG_OPTIONS = {
|
4
4
|
"api_key": "API key for OpenAI-compatible service (required)", # pragma: allowlist secret
|
5
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')",
|
6
|
+
"model": "Model name to use (e.g., 'gpt-4.1', 'gpt-4o', 'gpt-4-turbo', 'o3-mini', 'o4-mini', 'gemini-2.5-flash')",
|
7
7
|
"base_url": "API base URL (OpenAI-compatible endpoint)",
|
8
|
+
"azure_deployment_name": "Azure OpenAI deployment name (for Azure endpoints)",
|
8
9
|
"role": "Role description for the Agent Profile (e.g., 'software engineer')",
|
9
10
|
"temperature": "Sampling temperature (float, e.g., 0.0 - 2.0)",
|
10
11
|
"max_tokens": "Maximum tokens for model response (int)",
|
janito/cli/core/getters.py
CHANGED
@@ -1,31 +1,33 @@
|
|
1
|
-
"""Handlers for get-type CLI commands (show_config, list_providers, models, tools)."""
|
2
|
-
|
3
|
-
|
4
|
-
from janito.cli.cli_commands.
|
5
|
-
from janito.cli.cli_commands.
|
6
|
-
from janito.cli.cli_commands.
|
7
|
-
from
|
8
|
-
from
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
"
|
27
|
-
"
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
1
|
+
"""Handlers for get-type CLI commands (show_config, list_providers, models, tools)."""
|
2
|
+
import sys
|
3
|
+
|
4
|
+
from janito.cli.cli_commands.list_providers import handle_list_providers
|
5
|
+
from janito.cli.cli_commands.list_models import handle_list_models
|
6
|
+
from janito.cli.cli_commands.list_tools import handle_list_tools
|
7
|
+
from janito.cli.cli_commands.show_config import handle_show_config
|
8
|
+
from functools import partial
|
9
|
+
from janito.provider_registry import ProviderRegistry
|
10
|
+
|
11
|
+
GETTER_KEYS = ["show_config", "list_providers", "list_models", "list_tools"]
|
12
|
+
|
13
|
+
|
14
|
+
def handle_getter(args, config_mgr=None):
|
15
|
+
provider_instance = None
|
16
|
+
if getattr(args, "list_models", False):
|
17
|
+
provider = getattr(args, "provider", None)
|
18
|
+
if not provider:
|
19
|
+
import sys
|
20
|
+
print(
|
21
|
+
"Error: No provider selected. Please set a provider using '-p PROVIDER', '--set provider=name', or configure a provider."
|
22
|
+
)
|
23
|
+
sys.exit(1)
|
24
|
+
provider_instance = ProviderRegistry().get_instance(provider)
|
25
|
+
GETTER_DISPATCH = {
|
26
|
+
"list_providers": partial(handle_list_providers, args),
|
27
|
+
"list_models": partial(handle_list_models, args, provider_instance),
|
28
|
+
"list_tools": partial(handle_list_tools, args),
|
29
|
+
"show_config": partial(handle_show_config, args),
|
30
|
+
}
|
31
|
+
for arg in GETTER_KEYS:
|
32
|
+
if getattr(args, arg, False) and arg in GETTER_DISPATCH:
|
33
|
+
return GETTER_DISPATCH[arg]()
|