janito 3.12.0__py3-none-any.whl → 3.12.2__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.
@@ -1,162 +1,162 @@
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 _detect_dependencies_from_content(content, class_name):
17
- """Detect dependencies from module content."""
18
- dependencies = []
19
-
20
- if "import openai" in content or "from openai" in content:
21
- dependencies.append("openai")
22
- if "import zai" in content or "from zai" in content:
23
- dependencies.append("zai")
24
- if "import anthropic" in content or "from anthropic" in content:
25
- dependencies.append("anthropic")
26
- if "import google" in content or "from google" in content:
27
- dependencies.append("google-generativeai")
28
-
29
- # Remove openai from zai driver dependencies
30
- if "ZAIModelDriver" in class_name and "openai" in dependencies:
31
- dependencies.remove("openai")
32
-
33
- return dependencies
34
-
35
-
36
- def _check_dependency_status(dependencies):
37
- """Check if dependencies are available."""
38
- if not dependencies:
39
- return ["No external dependencies"]
40
-
41
- dep_status = []
42
- for dep in dependencies:
43
- try:
44
- importlib.import_module(dep)
45
- dep_status.append(f"✅ {dep}")
46
- except ImportError:
47
- dep_status.append(f"❌ {dep}")
48
-
49
- return dep_status
50
-
51
-
52
- def _get_single_driver_info(module_path, class_name):
53
- """Get information for a single driver."""
54
- try:
55
- module = importlib.import_module(module_path)
56
- driver_class = getattr(module, class_name)
57
-
58
- available = getattr(driver_class, "available", True)
59
- unavailable_reason = getattr(driver_class, "unavailable_reason", None)
60
-
61
- # Read module file to detect imports
62
- module_file = Path(module.__file__)
63
- with open(module_file, "r", encoding="utf-8") as f:
64
- content = f.read()
65
-
66
- dependencies = _detect_dependencies_from_content(content, class_name)
67
- dep_status = _check_dependency_status(dependencies)
68
-
69
- return {
70
- "name": class_name,
71
- "available": available,
72
- "reason": unavailable_reason,
73
- "dependencies": dep_status,
74
- }
75
-
76
- except (ImportError, AttributeError) as e:
77
- return {
78
- "name": class_name,
79
- "module": module_path,
80
- "available": False,
81
- "reason": str(e),
82
- "dependencies": ["❌ Module not found"],
83
- }
84
-
85
-
86
- def get_driver_info():
87
- """Get information about all available drivers."""
88
- drivers = []
89
-
90
- # Define known driver modules
91
- driver_modules = [
92
- ("janito.drivers.openai.driver", "OpenAIModelDriver"),
93
- ("janito.drivers.azure_openai.driver", "AzureOpenAIModelDriver"),
94
- ("janito.drivers.zai.driver", "ZAIModelDriver"),
95
- ("janito.drivers.cerebras.driver", "CerebrasModelDriver"),
96
- ]
97
-
98
- for module_path, class_name in driver_modules:
99
- driver_info = _get_single_driver_info(module_path, class_name)
100
- drivers.append(driver_info)
101
-
102
- return drivers
103
-
104
-
105
- def _create_driver_table(drivers):
106
- """Create and populate the drivers table."""
107
- table = Table(title="Available LLM Drivers")
108
- table.add_column("Driver", style="cyan", no_wrap=True)
109
- table.add_column("Status", style="bold")
110
- table.add_column("Dependencies", style="yellow")
111
-
112
- for driver in drivers:
113
- name = driver["name"]
114
-
115
- if driver["available"]:
116
- status = "[green]✅ Available[/green]"
117
- if driver["reason"]:
118
- status = f"[yellow]⚠️ Available ({driver['reason']})[/yellow]"
119
- else:
120
- status = f"[red]❌ Unavailable[/red]"
121
- if driver["reason"]:
122
- status = f"[red]❌ {driver['reason']}[/red]"
123
-
124
- deps = "\n".join(driver["dependencies"])
125
- table.add_row(name, status, deps)
126
-
127
- return table
128
-
129
-
130
- def _get_missing_dependencies(drivers):
131
- """Get list of missing dependencies."""
132
- missing_deps = []
133
- for driver in drivers:
134
- for dep_status in driver["dependencies"]:
135
- if dep_status.startswith("❌"):
136
- dep_name = dep_status.split()[1]
137
- if dep_name not in missing_deps:
138
- missing_deps.append(dep_name)
139
- return missing_deps
140
-
141
-
142
- def handle_list_drivers(args=None):
143
- """List all available LLM drivers with their status and dependencies."""
144
- drivers = get_driver_info()
145
-
146
- if not drivers:
147
- console.print("[red]No drivers found[/red]")
148
- return
149
-
150
- table = _create_driver_table(drivers)
151
- console.print(table)
152
-
153
- # Installation help - only show for missing dependencies
154
- missing_deps = _get_missing_dependencies(drivers)
155
- if missing_deps:
156
- console.print(
157
- f"\n[dim]💡 Install missing deps: pip install {' '.join(missing_deps)}[/dim]"
158
- )
159
-
160
-
161
- if __name__ == "__main__":
162
- handle_list_drivers()
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 _detect_dependencies_from_content(content, class_name):
17
+ """Detect dependencies from module content."""
18
+ dependencies = []
19
+
20
+ if "import openai" in content or "from openai" in content:
21
+ dependencies.append("openai")
22
+ if "import zai" in content or "from zai" in content:
23
+ dependencies.append("zai")
24
+ if "import anthropic" in content or "from anthropic" in content:
25
+ dependencies.append("anthropic")
26
+ if "import google" in content or "from google" in content:
27
+ dependencies.append("google-generativeai")
28
+
29
+ # Remove openai from zai driver dependencies
30
+ if "ZAIModelDriver" in class_name and "openai" in dependencies:
31
+ dependencies.remove("openai")
32
+
33
+ return dependencies
34
+
35
+
36
+ def _check_dependency_status(dependencies):
37
+ """Check if dependencies are available."""
38
+ if not dependencies:
39
+ return ["No external dependencies"]
40
+
41
+ dep_status = []
42
+ for dep in dependencies:
43
+ try:
44
+ importlib.import_module(dep)
45
+ dep_status.append(f"✅ {dep}")
46
+ except ImportError:
47
+ dep_status.append(f"❌ {dep}")
48
+
49
+ return dep_status
50
+
51
+
52
+ def _get_single_driver_info(module_path, class_name):
53
+ """Get information for a single driver."""
54
+ try:
55
+ module = importlib.import_module(module_path)
56
+ driver_class = getattr(module, class_name)
57
+
58
+ available = getattr(driver_class, "available", True)
59
+ unavailable_reason = getattr(driver_class, "unavailable_reason", None)
60
+
61
+ # Read module file to detect imports
62
+ module_file = Path(module.__file__)
63
+ with open(module_file, "r", encoding="utf-8") as f:
64
+ content = f.read()
65
+
66
+ dependencies = _detect_dependencies_from_content(content, class_name)
67
+ dep_status = _check_dependency_status(dependencies)
68
+
69
+ return {
70
+ "name": class_name,
71
+ "available": available,
72
+ "reason": unavailable_reason,
73
+ "dependencies": dep_status,
74
+ }
75
+
76
+ except (ImportError, AttributeError) as e:
77
+ return {
78
+ "name": class_name,
79
+ "module": module_path,
80
+ "available": False,
81
+ "reason": str(e),
82
+ "dependencies": ["❌ Module not found"],
83
+ }
84
+
85
+
86
+ def get_driver_info():
87
+ """Get information about all available drivers."""
88
+ drivers = []
89
+
90
+ # Define known driver modules
91
+ driver_modules = [
92
+ ("janito.drivers.openai.driver", "OpenAIModelDriver"),
93
+ ("janito.drivers.azure_openai.driver", "AzureOpenAIModelDriver"),
94
+ ("janito.drivers.zai.driver", "ZAIModelDriver"),
95
+ ("janito.drivers.cerebras.driver", "CerebrasModelDriver"),
96
+ ]
97
+
98
+ for module_path, class_name in driver_modules:
99
+ driver_info = _get_single_driver_info(module_path, class_name)
100
+ drivers.append(driver_info)
101
+
102
+ return drivers
103
+
104
+
105
+ def _create_driver_table(drivers):
106
+ """Create and populate the drivers table."""
107
+ table = Table(title="Available LLM Drivers")
108
+ table.add_column("Driver", style="cyan", no_wrap=True)
109
+ table.add_column("Status", style="bold")
110
+ table.add_column("Dependencies", style="yellow")
111
+
112
+ for driver in drivers:
113
+ name = driver["name"]
114
+
115
+ if driver["available"]:
116
+ status = "[green]✅ Available[/green]"
117
+ if driver["reason"]:
118
+ status = f"[yellow]⚠️ Available ({driver['reason']})[/yellow]"
119
+ else:
120
+ status = f"[red]❌ Unavailable[/red]"
121
+ if driver["reason"]:
122
+ status = f"[red]❌ {driver['reason']}[/red]"
123
+
124
+ deps = "\n".join(driver["dependencies"])
125
+ table.add_row(name, status, deps)
126
+
127
+ return table
128
+
129
+
130
+ def _get_missing_dependencies(drivers):
131
+ """Get list of missing dependencies."""
132
+ missing_deps = []
133
+ for driver in drivers:
134
+ for dep_status in driver["dependencies"]:
135
+ if dep_status.startswith("❌"):
136
+ dep_name = dep_status.split()[1]
137
+ if dep_name not in missing_deps:
138
+ missing_deps.append(dep_name)
139
+ return missing_deps
140
+
141
+
142
+ def handle_list_drivers(args=None):
143
+ """List all available LLM drivers with their status and dependencies."""
144
+ drivers = get_driver_info()
145
+
146
+ if not drivers:
147
+ console.print("[red]No drivers found[/red]")
148
+ return
149
+
150
+ table = _create_driver_table(drivers)
151
+ console.print(table)
152
+
153
+ # Installation help - only show for missing dependencies
154
+ missing_deps = _get_missing_dependencies(drivers)
155
+ if missing_deps:
156
+ console.print(
157
+ f"\n[dim]💡 Install missing deps: uv pip install {' '.join(missing_deps)}[/dim]"
158
+ )
159
+
160
+
161
+ if __name__ == "__main__":
162
+ handle_list_drivers()
@@ -1,107 +1,104 @@
1
- """
2
- CLI Command: List available system prompt profiles (default and user-specific)
3
- """
4
-
5
- from pathlib import Path
6
- import importlib.resources as resources
7
- from rich.console import Console
8
- from rich.table import Table
9
-
10
-
11
- _PREFIX = "system_prompt_template_"
12
- _SUFFIX = ".txt.j2"
13
-
14
-
15
- def _extract_profile_name(filename: str) -> str:
16
- """Return the human-readable profile name from template file name."""
17
- # Remove prefix & suffix and convert underscores back to spaces
18
- if filename.startswith(_PREFIX):
19
- filename = filename[len(_PREFIX) :]
20
- if filename.endswith(_SUFFIX):
21
- filename = filename[: -len(_SUFFIX)]
22
-
23
- # Convert to title case for consistent capitalization, but handle common acronyms
24
- name = filename.replace("_", " ")
25
-
26
- # Convert to proper title case with consistent capitalization
27
- name = filename.replace("_", " ")
28
-
29
- # Handle special cases and acronyms
30
- special_cases = {
31
- "python": "Python",
32
- "tools": "Tools",
33
- "model": "Model",
34
- "context": "Context",
35
- "developer": "Developer",
36
- "analyst": "Analyst",
37
- "conversation": "Conversation",
38
- "without": "Without",
39
- }
40
-
41
- words = name.split()
42
- capitalized_words = []
43
- for word in words:
44
- lower_word = word.lower()
45
- if lower_word in special_cases:
46
- capitalized_words.append(special_cases[lower_word])
47
- else:
48
- capitalized_words.append(word.capitalize())
49
-
50
- return " ".join(capitalized_words)
51
-
52
-
53
- def _gather_default_profiles():
54
- """Return list of built-in profile names bundled with janito."""
55
- profiles = []
56
- try:
57
- package_files = resources.files("janito.agent.templates.profiles")
58
- for path in package_files.iterdir():
59
- name = path.name
60
- if name.startswith(_PREFIX) and name.endswith(_SUFFIX):
61
- profiles.append(_extract_profile_name(name))
62
- except Exception:
63
- # If for some reason the resources are not available fall back to empty list
64
- pass
65
- return sorted(profiles, key=str.lower)
66
-
67
-
68
- def _gather_user_profiles():
69
- """Return list of user-defined profile names from ~/.janito/profiles directory."""
70
- user_dir = Path.home() / ".janito" / "profiles"
71
- profiles = []
72
- if user_dir.exists() and user_dir.is_dir():
73
- for path in user_dir.iterdir():
74
- if (
75
- path.is_file()
76
- and path.name.startswith(_PREFIX)
77
- and path.name.endswith(_SUFFIX)
78
- ):
79
- profiles.append(_extract_profile_name(path.name))
80
- return sorted(profiles, key=str.lower)
81
-
82
-
83
- def _print_profiles_table(default_profiles, user_profiles):
84
- console = Console()
85
- table = Table(title="Available System Prompt Profiles", box=None, show_lines=False)
86
- table.add_column("Profile Name", style="cyan", no_wrap=False)
87
- table.add_column("Source", style="magenta", no_wrap=True)
88
-
89
- for p in default_profiles:
90
- table.add_row(p, "default")
91
- for p in user_profiles:
92
- table.add_row(p, "user")
93
-
94
- console.print(table)
95
-
96
-
97
- def handle_list_profiles(args=None):
98
- """Entry point for the --list-profiles CLI flag."""
99
- default_profiles = _gather_default_profiles()
100
- user_profiles = _gather_user_profiles()
101
-
102
- if not default_profiles and not user_profiles:
103
- print("No profiles found.")
104
- return
105
-
106
- _print_profiles_table(default_profiles, user_profiles)
107
- return
1
+ """
2
+ CLI Command: List available system prompt profiles (default and user-specific)
3
+ """
4
+
5
+ from pathlib import Path
6
+ import importlib.resources as resources
7
+ from rich.console import Console
8
+ from rich.table import Table
9
+
10
+
11
+ _PREFIX = "system_prompt_template_"
12
+ _SUFFIX = ".txt.j2"
13
+
14
+
15
+ def _extract_profile_name(filename: str) -> str:
16
+ """Return the human-readable profile name from template file name."""
17
+ # Remove prefix & suffix and convert underscores back to spaces
18
+ if filename.startswith(_PREFIX):
19
+ filename = filename[len(_PREFIX) :]
20
+ if filename.endswith(_SUFFIX):
21
+ filename = filename[: -len(_SUFFIX)]
22
+
23
+ # Convert to title case for consistent capitalization, but handle common acronyms
24
+ name = filename.replace("_", " ")
25
+
26
+ # Handle special cases and acronyms
27
+ special_cases = {
28
+ "python": "Python",
29
+ "tools": "Tools",
30
+ "model": "Model",
31
+ "context": "Context",
32
+ "developer": "Developer",
33
+ "analyst": "Analyst",
34
+ "conversation": "Conversation",
35
+ "without": "Without",
36
+ }
37
+
38
+ words = name.split()
39
+ capitalized_words = []
40
+ for word in words:
41
+ lower_word = word.lower()
42
+ if lower_word in special_cases:
43
+ capitalized_words.append(special_cases[lower_word])
44
+ else:
45
+ capitalized_words.append(word.capitalize())
46
+
47
+ return " ".join(capitalized_words)
48
+
49
+
50
+ def _gather_default_profiles():
51
+ """Return list of built-in profile names bundled with janito."""
52
+ profiles = []
53
+ try:
54
+ package_files = resources.files("janito.agent.templates.profiles")
55
+ for path in package_files.iterdir():
56
+ name = path.name
57
+ if name.startswith(_PREFIX) and name.endswith(_SUFFIX):
58
+ profiles.append(_extract_profile_name(name))
59
+ except Exception:
60
+ # If for some reason the resources are not available fall back to empty list
61
+ pass
62
+ return sorted(profiles, key=str.lower)
63
+
64
+
65
+ def _gather_user_profiles():
66
+ """Return list of user-defined profile names from ~/.janito/profiles directory."""
67
+ user_dir = Path.home() / ".janito" / "profiles"
68
+ profiles = []
69
+ if user_dir.exists() and user_dir.is_dir():
70
+ for path in user_dir.iterdir():
71
+ if (
72
+ path.is_file()
73
+ and path.name.startswith(_PREFIX)
74
+ and path.name.endswith(_SUFFIX)
75
+ ):
76
+ profiles.append(_extract_profile_name(path.name))
77
+ return sorted(profiles, key=str.lower)
78
+
79
+
80
+ def _print_profiles_table(default_profiles, user_profiles):
81
+ console = Console()
82
+ table = Table(title="Available System Prompt Profiles", box=None, show_lines=False)
83
+ table.add_column("Profile Name", style="cyan", no_wrap=False)
84
+ table.add_column("Source", style="magenta", no_wrap=True)
85
+
86
+ for p in default_profiles:
87
+ table.add_row(p, "default")
88
+ for p in user_profiles:
89
+ table.add_row(p, "user")
90
+
91
+ console.print(table)
92
+
93
+
94
+ def handle_list_profiles(args=None):
95
+ """Entry point for the --list-profiles CLI flag."""
96
+ default_profiles = _gather_default_profiles()
97
+ user_profiles = _gather_user_profiles()
98
+
99
+ if not default_profiles and not user_profiles:
100
+ print("No profiles found.")
101
+ return
102
+
103
+ _print_profiles_table(default_profiles, user_profiles)
104
+ return