janito 3.12.1__py3-none-any.whl → 3.12.3__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,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
@@ -1,166 +1,166 @@
1
- """
2
- CLI Command: Show the resolved system prompt for the main agent (single-shot mode)
3
-
4
- Supports --profile to select a profile-specific system prompt template.
5
- """
6
-
7
- from janito.cli.core.runner import prepare_llm_driver_config
8
- from janito.platform_discovery import PlatformDiscovery
9
- from pathlib import Path
10
- from jinja2 import Template
11
- import importlib.resources
12
- import importlib.resources as resources
13
- import re
14
-
15
-
16
- def _compute_permission_string(args):
17
- from janito.tools.tool_base import ToolPermissions
18
-
19
- read = getattr(args, "read", False)
20
- write = getattr(args, "write", False)
21
- execute = getattr(args, "exec", False)
22
- allowed = ToolPermissions(read=read, write=write, execute=execute)
23
- perm_str = ""
24
- if allowed.read:
25
- perm_str += "r"
26
- if allowed.write:
27
- perm_str += "w"
28
- if allowed.execute:
29
- perm_str += "x"
30
- return perm_str or None
31
-
32
-
33
- def _prepare_context(args, agent_role, allowed_permissions):
34
- context = {}
35
- context["role"] = agent_role or "developer"
36
- context["profile"] = getattr(args, "profile", None)
37
- context["allowed_permissions"] = allowed_permissions
38
- context["emoji_enabled"] = getattr(args, "emoji", False)
39
- if allowed_permissions and "x" in allowed_permissions:
40
- pd = PlatformDiscovery()
41
- context["platform"] = pd.get_platform_name()
42
- context["python_version"] = pd.get_python_version()
43
- context["shell_info"] = pd.detect_shell()
44
- return context
45
-
46
-
47
- def _load_template(profile, templates_dir):
48
- if profile:
49
- sanitized_profile = re.sub(r"\\s+", "_", profile.strip())
50
- template_filename = f"system_prompt_template_{sanitized_profile}.txt.j2"
51
- template_path = templates_dir / template_filename
52
- else:
53
- return None, None
54
- template_content = None
55
- if template_path and template_path.exists():
56
- with open(template_path, "r", encoding="utf-8") as file:
57
- template_content = file.read()
58
- else:
59
- try:
60
- with importlib.resources.files("janito.agent.templates.profiles").joinpath(
61
- template_filename
62
- ).open("r", encoding="utf-8") as file:
63
- template_content = file.read()
64
- except (FileNotFoundError, ModuleNotFoundError, AttributeError):
65
- # Also check user profiles directory
66
- from pathlib import Path
67
- import os
68
-
69
- user_profiles_dir = Path(os.path.expanduser("~/.janito/profiles"))
70
- user_template_path = user_profiles_dir / template_filename
71
- if user_template_path.exists():
72
- with open(user_template_path, "r", encoding="utf-8") as file:
73
- template_content = file.read()
74
- else:
75
- template_content = None
76
- return template_filename, template_content
77
- return template_filename, template_content
78
-
79
-
80
- def _print_debug_info(debug_flag, template_filename, allowed_permissions, context):
81
- if debug_flag:
82
- from rich import print as rich_print
83
-
84
- rich_print(
85
- f"[bold magenta][DEBUG][/bold magenta] Rendering system prompt template '[cyan]{template_filename}[/cyan]' with allowed_permissions: [yellow]{allowed_permissions}[/yellow]"
86
- )
87
- rich_print(
88
- f"[bold magenta][DEBUG][/bold magenta] Template context: [green]{context}[/green]"
89
- )
90
-
91
-
92
- def handle_show_system_prompt(args):
93
- from janito.cli.main_cli import MODIFIER_KEYS
94
-
95
- modifiers = {
96
- k: getattr(args, k) for k in MODIFIER_KEYS if getattr(args, k, None) is not None
97
- }
98
- provider, llm_driver_config, agent_role = prepare_llm_driver_config(args, modifiers)
99
- if provider is None or llm_driver_config is None:
100
- print("Error: Could not resolve provider or LLM driver config.")
101
- return
102
-
103
- allowed_permissions = _compute_permission_string(args)
104
- context = _prepare_context(args, agent_role, allowed_permissions)
105
-
106
- # Debug flag detection
107
- import sys
108
-
109
- debug_flag = False
110
- try:
111
- debug_flag = hasattr(sys, "argv") and (
112
- "--debug" in sys.argv or "--verbose" in sys.argv or "-v" in sys.argv
113
- )
114
- except Exception:
115
- pass
116
-
117
- templates_dir = (
118
- Path(__file__).parent.parent.parent / "agent" / "templates" / "profiles"
119
- )
120
- profile = getattr(args, "profile", None)
121
-
122
- # Handle --market flag mapping to Market Analyst profile
123
- if profile is None and getattr(args, "market", False):
124
- profile = "Market Analyst"
125
-
126
- # Handle --developer flag mapping to Developer With Python Tools profile
127
- if profile is None and getattr(args, "developer", False):
128
- profile = "Developer With Python Tools"
129
-
130
- if not profile:
131
- print(
132
- "[janito] No profile specified. The main agent runs without a system prompt template.\n"
133
- "Use --profile PROFILE to view a profile-specific system prompt."
134
- )
135
- return
136
-
137
- template_filename, template_content = _load_template(profile, templates_dir)
138
- _print_debug_info(debug_flag, template_filename, allowed_permissions, context)
139
-
140
- if not template_content:
141
- # Try to load directly from package resources as fallback
142
- try:
143
- template_content = (
144
- resources.files("janito.agent.templates.profiles")
145
- .joinpath(
146
- f"system_prompt_template_{profile.lower().replace(' ', '_')}.txt.j2"
147
- )
148
- .read_text(encoding="utf-8")
149
- )
150
- except (FileNotFoundError, ModuleNotFoundError, AttributeError):
151
- print(
152
- f"[janito] Could not find profile '{profile}'. This may be a configuration issue."
153
- )
154
- return
155
-
156
- template = Template(template_content)
157
- system_prompt = template.render(**context)
158
- system_prompt = re.sub(r"\n{3,}", "\n\n", system_prompt)
159
-
160
- # Use the actual profile name for display, not the resolved value
161
- display_profile = profile or "main"
162
- print(f"\n--- System Prompt (resolved, profile: {display_profile}) ---\n")
163
- print(system_prompt)
164
- print("\n-------------------------------\n")
165
- if agent_role:
166
- print(f"[Role: {agent_role}]")
1
+ """
2
+ CLI Command: Show the resolved system prompt for the main agent (single-shot mode)
3
+
4
+ Supports --profile to select a profile-specific system prompt template.
5
+ """
6
+
7
+ from janito.cli.core.runner import prepare_llm_driver_config
8
+ from janito.platform_discovery import PlatformDiscovery
9
+ from pathlib import Path
10
+ from jinja2 import Template
11
+ import importlib.resources
12
+ import importlib.resources as resources
13
+ import re
14
+
15
+
16
+ def _compute_permission_string(args):
17
+ from janito.tools.tool_base import ToolPermissions
18
+
19
+ read = getattr(args, "read", False)
20
+ write = getattr(args, "write", False)
21
+ execute = getattr(args, "exec", False)
22
+ allowed = ToolPermissions(read=read, write=write, execute=execute)
23
+ perm_str = ""
24
+ if allowed.read:
25
+ perm_str += "r"
26
+ if allowed.write:
27
+ perm_str += "w"
28
+ if allowed.execute:
29
+ perm_str += "x"
30
+ return perm_str or None
31
+
32
+
33
+ def _prepare_context(args, agent_role, allowed_permissions):
34
+ context = {}
35
+ context["role"] = agent_role or "developer"
36
+ context["profile"] = getattr(args, "profile", None)
37
+ context["allowed_permissions"] = allowed_permissions
38
+ context["emoji_enabled"] = getattr(args, "emoji", False)
39
+ if allowed_permissions and "x" in allowed_permissions:
40
+ pd = PlatformDiscovery()
41
+ context["platform"] = pd.get_platform_name()
42
+ context["python_version"] = pd.get_python_version()
43
+ context["shell_info"] = pd.detect_shell()
44
+ return context
45
+
46
+
47
+ def _load_template(profile, templates_dir):
48
+ if profile:
49
+ sanitized_profile = re.sub(r"\\s+", "_", profile.strip())
50
+ template_filename = f"system_prompt_template_{sanitized_profile}.txt.j2"
51
+ template_path = templates_dir / template_filename
52
+ else:
53
+ return None, None
54
+ template_content = None
55
+ if template_path and template_path.exists():
56
+ with open(template_path, "r", encoding="utf-8") as file:
57
+ template_content = file.read()
58
+ else:
59
+ try:
60
+ with importlib.resources.files("janito.agent.templates.profiles").joinpath(
61
+ template_filename
62
+ ).open("r", encoding="utf-8") as file:
63
+ template_content = file.read()
64
+ except (FileNotFoundError, ModuleNotFoundError, AttributeError):
65
+ # Also check user profiles directory
66
+ from pathlib import Path
67
+ import os
68
+
69
+ user_profiles_dir = Path(os.path.expanduser("~/.janito/profiles"))
70
+ user_template_path = user_profiles_dir / template_filename
71
+ if user_template_path.exists():
72
+ with open(user_template_path, "r", encoding="utf-8") as file:
73
+ template_content = file.read()
74
+ else:
75
+ template_content = None
76
+ return template_filename, template_content
77
+ return template_filename, template_content
78
+
79
+
80
+ def _print_debug_info(debug_flag, template_filename, allowed_permissions, context):
81
+ if debug_flag:
82
+ from rich import print as rich_print
83
+
84
+ rich_print(
85
+ f"[bold magenta][DEBUG][/bold magenta] Rendering system prompt template '[cyan]{template_filename}[/cyan]' with allowed_permissions: [yellow]{allowed_permissions}[/yellow]"
86
+ )
87
+ rich_print(
88
+ f"[bold magenta][DEBUG][/bold magenta] Template context: [green]{context}[/green]"
89
+ )
90
+
91
+
92
+ def handle_show_system_prompt(args):
93
+ from janito.cli.main_cli import MODIFIER_KEYS
94
+
95
+ modifiers = {
96
+ k: getattr(args, k) for k in MODIFIER_KEYS if getattr(args, k, None) is not None
97
+ }
98
+ provider, llm_driver_config, agent_role = prepare_llm_driver_config(args, modifiers)
99
+ if provider is None or llm_driver_config is None:
100
+ print("Error: Could not resolve provider or LLM driver config.")
101
+ return
102
+
103
+ allowed_permissions = _compute_permission_string(args)
104
+ context = _prepare_context(args, agent_role, allowed_permissions)
105
+
106
+ # Debug flag detection
107
+ import sys
108
+
109
+ debug_flag = False
110
+ try:
111
+ debug_flag = hasattr(sys, "argv") and (
112
+ "--debug" in sys.argv or "--verbose" in sys.argv or "-v" in sys.argv
113
+ )
114
+ except Exception:
115
+ pass
116
+
117
+ templates_dir = (
118
+ Path(__file__).parent.parent.parent / "agent" / "templates" / "profiles"
119
+ )
120
+ profile = getattr(args, "profile", None)
121
+
122
+ # Handle --market flag mapping to Market Analyst profile
123
+ if profile is None and getattr(args, "market", False):
124
+ profile = "Market Analyst"
125
+
126
+ # Handle --developer flag mapping to Developer profile
127
+ if profile is None and getattr(args, "developer", False):
128
+ profile = "Developer"
129
+
130
+ if not profile:
131
+ print(
132
+ "[janito] No profile specified. The main agent runs without a system prompt template.\n"
133
+ "Use --profile PROFILE to view a profile-specific system prompt."
134
+ )
135
+ return
136
+
137
+ template_filename, template_content = _load_template(profile, templates_dir)
138
+ _print_debug_info(debug_flag, template_filename, allowed_permissions, context)
139
+
140
+ if not template_content:
141
+ # Try to load directly from package resources as fallback
142
+ try:
143
+ template_content = (
144
+ resources.files("janito.agent.templates.profiles")
145
+ .joinpath(
146
+ f"system_prompt_template_{profile.lower().replace(' ', '_')}.txt.j2"
147
+ )
148
+ .read_text(encoding="utf-8")
149
+ )
150
+ except (FileNotFoundError, ModuleNotFoundError, AttributeError):
151
+ print(
152
+ f"[janito] Could not find profile '{profile}'. This may be a configuration issue."
153
+ )
154
+ return
155
+
156
+ template = Template(template_content)
157
+ system_prompt = template.render(**context)
158
+ system_prompt = re.sub(r"\n{3,}", "\n\n", system_prompt)
159
+
160
+ # Use the actual profile name for display, not the resolved value
161
+ display_profile = profile or "main"
162
+ print(f"\n--- System Prompt (resolved, profile: {display_profile}) ---\n")
163
+ print(system_prompt)
164
+ print("\n-------------------------------\n")
165
+ if agent_role:
166
+ print(f"[Role: {agent_role}]")