janito 2.10.0__py3-none-any.whl → 2.14.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/setup_agent.py +1 -1
- janito/cli/chat_mode/session.py +9 -0
- janito/cli/cli_commands/list_drivers.py +137 -0
- janito/cli/core/getters.py +6 -1
- janito/cli/core/model_guesser.py +51 -0
- janito/cli/core/runner.py +13 -1
- janito/cli/main_cli.py +15 -10
- janito/drivers/openai/driver.py +3 -2
- janito/drivers/zai/__init__.py +1 -0
- janito/drivers/zai/driver.py +476 -0
- janito/mkdocs.yml +1 -1
- janito/providers/__init__.py +1 -0
- janito/providers/alibaba/model_info.py +7 -0
- janito/providers/alibaba/provider.py +1 -1
- janito/providers/zai/__init__.py +1 -0
- janito/providers/zai/model_info.py +38 -0
- janito/providers/zai/provider.py +131 -0
- janito/providers/zai/schema_generator.py +135 -0
- {janito-2.10.0.dist-info → janito-2.14.0.dist-info}/METADATA +1 -1
- {janito-2.10.0.dist-info → janito-2.14.0.dist-info}/RECORD +24 -18
- janito/docs/PROVIDERS.md +0 -224
- janito/drivers/driver_registry.py +0 -27
- {janito-2.10.0.dist-info → janito-2.14.0.dist-info}/WHEEL +0 -0
- {janito-2.10.0.dist-info → janito-2.14.0.dist-info}/entry_points.txt +0 -0
- {janito-2.10.0.dist-info → janito-2.14.0.dist-info}/licenses/LICENSE +0 -0
- {janito-2.10.0.dist-info → janito-2.14.0.dist-info}/top_level.txt +0 -0
janito/agent/setup_agent.py
CHANGED
@@ -12,7 +12,7 @@ from queue import Queue
|
|
12
12
|
from rich import print as rich_print
|
13
13
|
from janito.tools import get_local_tools_adapter
|
14
14
|
from janito.llm.agent import LLMAgent
|
15
|
-
|
15
|
+
|
16
16
|
from janito.platform_discovery import PlatformDiscovery
|
17
17
|
from janito.tools.tool_base import ToolPermissions
|
18
18
|
from janito.tools.permissions import get_global_allowed_permissions
|
janito/cli/chat_mode/session.py
CHANGED
@@ -109,6 +109,9 @@ class ChatSession:
|
|
109
109
|
)
|
110
110
|
self._support = False
|
111
111
|
|
112
|
+
# Check if multi-line mode should be enabled by default
|
113
|
+
self.multi_line_mode = getattr(args, "multi", False) if args else False
|
114
|
+
|
112
115
|
def _select_profile_and_role(self, args, role):
|
113
116
|
profile = getattr(args, "profile", None) if args is not None else None
|
114
117
|
role_arg = getattr(args, "role", None) if args is not None else None
|
@@ -213,6 +216,11 @@ class ChatSession:
|
|
213
216
|
f"[green]Working Dir:[/green] {cwd_display} | {priv_status}"
|
214
217
|
)
|
215
218
|
|
219
|
+
if self.multi_line_mode:
|
220
|
+
self.console.print(
|
221
|
+
"[blue]Multi-line input mode enabled (Esc+Enter or Ctrl+D to submit)[/blue]"
|
222
|
+
)
|
223
|
+
|
216
224
|
from janito.cli.chat_mode.shell.commands._priv_check import (
|
217
225
|
user_has_any_privileges,
|
218
226
|
)
|
@@ -305,6 +313,7 @@ class ChatSession:
|
|
305
313
|
bottom_toolbar=lambda: get_toolbar_func(
|
306
314
|
self.performance_collector, 0, self.shell_state
|
307
315
|
)(),
|
316
|
+
multiline=self.multi_line_mode,
|
308
317
|
)
|
309
318
|
|
310
319
|
def _handle_input(self, session):
|
@@ -0,0 +1,137 @@
|
|
1
|
+
"""
|
2
|
+
CLI Command: List available LLM drivers and their dependencies
|
3
|
+
"""
|
4
|
+
|
5
|
+
import importlib
|
6
|
+
import sys
|
7
|
+
from pathlib import Path
|
8
|
+
from rich.console import Console
|
9
|
+
from rich.table import Table
|
10
|
+
from rich.panel import Panel
|
11
|
+
from rich.text import Text
|
12
|
+
|
13
|
+
console = Console()
|
14
|
+
|
15
|
+
|
16
|
+
def get_driver_info():
|
17
|
+
"""Get information about all available drivers."""
|
18
|
+
drivers = []
|
19
|
+
|
20
|
+
# Define known driver modules
|
21
|
+
driver_modules = [
|
22
|
+
("janito.drivers.openai.driver", "OpenAIModelDriver"),
|
23
|
+
("janito.drivers.azure_openai.driver", "AzureOpenAIModelDriver"),
|
24
|
+
("janito.drivers.zai.driver", "ZAIModelDriver"),
|
25
|
+
]
|
26
|
+
|
27
|
+
for module_path, class_name in driver_modules:
|
28
|
+
try:
|
29
|
+
# Import the module
|
30
|
+
module = importlib.import_module(module_path)
|
31
|
+
driver_class = getattr(module, class_name)
|
32
|
+
|
33
|
+
# Get availability info
|
34
|
+
available = getattr(driver_class, 'available', True)
|
35
|
+
unavailable_reason = getattr(driver_class, 'unavailable_reason', None)
|
36
|
+
|
37
|
+
# Get dependencies from module imports
|
38
|
+
dependencies = []
|
39
|
+
module_file = Path(module.__file__)
|
40
|
+
|
41
|
+
# Read module file to detect imports
|
42
|
+
with open(module_file, 'r', encoding='utf-8') as f:
|
43
|
+
content = f.read()
|
44
|
+
|
45
|
+
# Simple dependency detection
|
46
|
+
if 'import openai' in content or 'from openai' in content:
|
47
|
+
dependencies.append('openai')
|
48
|
+
if 'import zai' in content or 'from zai' in content:
|
49
|
+
dependencies.append('zai')
|
50
|
+
if 'import anthropic' in content or 'from anthropic' in content:
|
51
|
+
dependencies.append('anthropic')
|
52
|
+
if 'import google' in content or 'from google' in content:
|
53
|
+
dependencies.append('google-generativeai')
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
# Remove duplicates while preserving order
|
58
|
+
seen = set()
|
59
|
+
dependencies = [dep for dep in dependencies if not (dep in seen or seen.add(dep))]
|
60
|
+
|
61
|
+
# Check if dependencies are available
|
62
|
+
dep_status = []
|
63
|
+
for dep in dependencies:
|
64
|
+
try:
|
65
|
+
importlib.import_module(dep)
|
66
|
+
dep_status.append(f"✅ {dep}")
|
67
|
+
except ImportError:
|
68
|
+
dep_status.append(f"❌ {dep}")
|
69
|
+
|
70
|
+
if not dependencies:
|
71
|
+
dep_status = ["No external dependencies"]
|
72
|
+
|
73
|
+
drivers.append({
|
74
|
+
'name': class_name,
|
75
|
+
'available': available,
|
76
|
+
'reason': unavailable_reason,
|
77
|
+
'dependencies': dep_status
|
78
|
+
})
|
79
|
+
|
80
|
+
except (ImportError, AttributeError) as e:
|
81
|
+
drivers.append({
|
82
|
+
'name': class_name,
|
83
|
+
'module': module_path,
|
84
|
+
'available': False,
|
85
|
+
'reason': str(e),
|
86
|
+
'dependencies': ["❌ Module not found"]
|
87
|
+
})
|
88
|
+
|
89
|
+
return drivers
|
90
|
+
|
91
|
+
|
92
|
+
def handle_list_drivers(args=None):
|
93
|
+
"""List all available LLM drivers with their status and dependencies."""
|
94
|
+
drivers = get_driver_info()
|
95
|
+
|
96
|
+
if not drivers:
|
97
|
+
console.print("[red]No drivers found[/red]")
|
98
|
+
return
|
99
|
+
|
100
|
+
# Create table
|
101
|
+
table = Table(title="Available LLM Drivers")
|
102
|
+
table.add_column("Driver", style="cyan", no_wrap=True)
|
103
|
+
table.add_column("Status", style="bold")
|
104
|
+
table.add_column("Dependencies", style="yellow")
|
105
|
+
|
106
|
+
for driver in drivers:
|
107
|
+
name = driver['name']
|
108
|
+
|
109
|
+
if driver['available']:
|
110
|
+
status = "[green]✅ Available[/green]"
|
111
|
+
if driver['reason']:
|
112
|
+
status = f"[yellow]⚠️ Available ({driver['reason']})[/yellow]"
|
113
|
+
else:
|
114
|
+
status = f"[red]❌ Unavailable[/red]"
|
115
|
+
if driver['reason']:
|
116
|
+
status = f"[red]❌ {driver['reason']}[/red]"
|
117
|
+
|
118
|
+
deps = "\n".join(driver['dependencies'])
|
119
|
+
|
120
|
+
table.add_row(name, status, deps)
|
121
|
+
|
122
|
+
console.print(table)
|
123
|
+
|
124
|
+
# Installation help
|
125
|
+
# Get unique missing dependencies
|
126
|
+
missing_deps = set()
|
127
|
+
for driver in drivers:
|
128
|
+
for dep_status in driver['dependencies']:
|
129
|
+
if dep_status.startswith('❌'):
|
130
|
+
missing_deps.add(dep_status[2:].strip())
|
131
|
+
|
132
|
+
if missing_deps:
|
133
|
+
console.print(f"\n[dim]💡 Install missing deps: pip install {' '.join(sorted(missing_deps))}[/dim]")
|
134
|
+
|
135
|
+
|
136
|
+
if __name__ == "__main__":
|
137
|
+
handle_list_drivers()
|
janito/cli/core/getters.py
CHANGED
@@ -7,6 +7,7 @@ from janito.cli.cli_commands.list_models import handle_list_models
|
|
7
7
|
from janito.cli.cli_commands.list_tools import handle_list_tools
|
8
8
|
from janito.cli.cli_commands.show_config import handle_show_config
|
9
9
|
from janito.cli.cli_commands.list_config import handle_list_config
|
10
|
+
from janito.cli.cli_commands.list_drivers import handle_list_drivers
|
10
11
|
from functools import partial
|
11
12
|
from janito.provider_registry import ProviderRegistry
|
12
13
|
|
@@ -17,6 +18,7 @@ GETTER_KEYS = [
|
|
17
18
|
"list_models",
|
18
19
|
"list_tools",
|
19
20
|
"list_config",
|
21
|
+
"list_drivers",
|
20
22
|
]
|
21
23
|
|
22
24
|
|
@@ -42,7 +44,10 @@ def handle_getter(args, config_mgr=None):
|
|
42
44
|
"list_profiles": partial(handle_list_profiles, args),
|
43
45
|
"show_config": partial(handle_show_config, args),
|
44
46
|
"list_config": partial(handle_list_config, args),
|
47
|
+
"list_drivers": partial(handle_list_drivers, args),
|
45
48
|
}
|
46
49
|
for arg in GETTER_KEYS:
|
47
50
|
if getattr(args, arg, False) and arg in GETTER_DISPATCH:
|
48
|
-
|
51
|
+
GETTER_DISPATCH[arg]()
|
52
|
+
import sys
|
53
|
+
sys.exit(0)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
"""
|
2
|
+
Module for guessing the provider based on model names.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from janito.providers.registry import LLMProviderRegistry
|
6
|
+
|
7
|
+
|
8
|
+
def guess_provider_from_model(model_name: str) -> str:
|
9
|
+
"""
|
10
|
+
Guess the provider based on the model name.
|
11
|
+
|
12
|
+
Args:
|
13
|
+
model_name: The name of the model to guess the provider for
|
14
|
+
|
15
|
+
Returns:
|
16
|
+
The provider name if a match is found, None otherwise
|
17
|
+
"""
|
18
|
+
if not model_name:
|
19
|
+
return None
|
20
|
+
|
21
|
+
model_name = model_name.lower()
|
22
|
+
|
23
|
+
# Check each provider's models
|
24
|
+
for provider_name in LLMProviderRegistry.list_providers():
|
25
|
+
provider_class = LLMProviderRegistry.get(provider_name)
|
26
|
+
if not provider_class:
|
27
|
+
continue
|
28
|
+
|
29
|
+
# Get model specs for this provider
|
30
|
+
try:
|
31
|
+
if hasattr(provider_class, 'MODEL_SPECS'):
|
32
|
+
model_specs = provider_class.MODEL_SPECS
|
33
|
+
for spec_model_name in model_specs.keys():
|
34
|
+
if spec_model_name.lower() == model_name:
|
35
|
+
return provider_name
|
36
|
+
|
37
|
+
# Handle special cases like moonshotai
|
38
|
+
if provider_name == "moonshotai":
|
39
|
+
try:
|
40
|
+
from janito.providers.moonshotai.model_info import MOONSHOTAI_MODEL_SPECS
|
41
|
+
for spec_model_name in MOONSHOTAI_MODEL_SPECS.keys():
|
42
|
+
if spec_model_name.lower() == model_name:
|
43
|
+
return "moonshotai"
|
44
|
+
except ImportError:
|
45
|
+
pass
|
46
|
+
|
47
|
+
except Exception:
|
48
|
+
# Skip providers that have issues accessing model specs
|
49
|
+
continue
|
50
|
+
|
51
|
+
return None
|
janito/cli/core/runner.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
from janito.llm.driver_config import LLMDriverConfig
|
4
4
|
from janito.provider_config import get_config_provider
|
5
|
+
from janito.cli.core.model_guesser import guess_provider_from_model as _guess_provider_from_model
|
5
6
|
from janito.cli.verbose_output import print_verbose_info
|
6
7
|
|
7
8
|
|
@@ -14,6 +15,17 @@ def _choose_provider(args):
|
|
14
15
|
"Default provider", provider, style="magenta", align_content=True
|
15
16
|
)
|
16
17
|
elif provider is None:
|
18
|
+
# Try to guess provider based on model name if -m is provided
|
19
|
+
model = getattr(args, "model", None)
|
20
|
+
if model:
|
21
|
+
guessed_provider = _guess_provider_from_model(model)
|
22
|
+
if guessed_provider:
|
23
|
+
if getattr(args, "verbose", False):
|
24
|
+
print_verbose_info(
|
25
|
+
"Guessed provider", guessed_provider, style="magenta", align_content=True
|
26
|
+
)
|
27
|
+
return guessed_provider
|
28
|
+
|
17
29
|
print(
|
18
30
|
"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
31
|
)
|
@@ -191,4 +203,4 @@ def handle_runner(
|
|
191
203
|
|
192
204
|
|
193
205
|
def get_prompt_mode(args):
|
194
|
-
return "single_shot" if getattr(args, "user_prompt", None) else "chat_mode"
|
206
|
+
return "single_shot" if getattr(args, "user_prompt", None) else "chat_mode"
|
janito/cli/main_cli.py
CHANGED
@@ -21,6 +21,13 @@ definition = [
|
|
21
21
|
"help": "Disable path security: allow tool arguments to use any file/directory path (DANGEROUS)",
|
22
22
|
},
|
23
23
|
),
|
24
|
+
(
|
25
|
+
["--multi"],
|
26
|
+
{
|
27
|
+
"action": "store_true",
|
28
|
+
"help": "Start chat mode with multi-line input as default (no need for /multi command)",
|
29
|
+
},
|
30
|
+
),
|
24
31
|
(
|
25
32
|
["--profile"],
|
26
33
|
{
|
@@ -110,6 +117,10 @@ definition = [
|
|
110
117
|
["--list-providers"],
|
111
118
|
{"action": "store_true", "help": "List supported LLM providers"},
|
112
119
|
),
|
120
|
+
(
|
121
|
+
["--list-drivers"],
|
122
|
+
{"action": "store_true", "help": "List available LLM drivers and their dependencies"},
|
123
|
+
),
|
113
124
|
(
|
114
125
|
["-l", "--list-models"],
|
115
126
|
{"action": "store_true", "help": "List all supported models"},
|
@@ -199,6 +210,7 @@ GETTER_KEYS = [
|
|
199
210
|
"list_models",
|
200
211
|
"list_tools",
|
201
212
|
"list_config",
|
213
|
+
"list_drivers",
|
202
214
|
]
|
203
215
|
|
204
216
|
|
@@ -314,14 +326,8 @@ class JanitoCLI:
|
|
314
326
|
if run_mode == RunMode.SET:
|
315
327
|
if self._run_set_mode():
|
316
328
|
return
|
317
|
-
# Special handling: provider is not required for list_providers, list_tools, show_config
|
318
|
-
if run_mode == RunMode.GET
|
319
|
-
self.args.list_providers
|
320
|
-
or self.args.list_tools
|
321
|
-
or self.args.list_profiles
|
322
|
-
or self.args.show_config
|
323
|
-
or self.args.list_config
|
324
|
-
):
|
329
|
+
# Special handling: provider is not required for list_providers, list_tools, show_config, list_drivers
|
330
|
+
if run_mode == RunMode.GET:
|
325
331
|
self._maybe_print_verbose_provider_model()
|
326
332
|
handle_getter(self.args)
|
327
333
|
return
|
@@ -357,8 +363,7 @@ class JanitoCLI:
|
|
357
363
|
agent_role,
|
358
364
|
verbose_tools=self.args.verbose_tools,
|
359
365
|
)
|
360
|
-
|
361
|
-
handle_getter(self.args)
|
366
|
+
|
362
367
|
|
363
368
|
def _run_set_mode(self):
|
364
369
|
if handle_api_key_set(self.args):
|
janito/drivers/openai/driver.py
CHANGED
@@ -44,9 +44,10 @@ class OpenAIModelDriver(LLMDriver):
|
|
44
44
|
|
45
45
|
tool_classes = self.tools_adapter.get_tool_classes()
|
46
46
|
tool_schemas = generate_tool_schemas(tool_classes)
|
47
|
-
|
47
|
+
if tool_schemas: # Only add tools if we have actual schemas
|
48
|
+
api_kwargs["tools"] = tool_schemas
|
48
49
|
except Exception as e:
|
49
|
-
|
50
|
+
# Don't add empty tools array - some providers reject it
|
50
51
|
if hasattr(config, "verbose_api") and config.verbose_api:
|
51
52
|
print(f"[OpenAIModelDriver] Tool schema generation failed: {e}")
|
52
53
|
# OpenAI-specific parameters
|
@@ -0,0 +1 @@
|
|
1
|
+
# Z.AI driver package
|