janito 2.22.0__py3-none-any.whl → 2.24.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.
Files changed (67) hide show
  1. janito/README.md +0 -0
  2. janito/agent/setup_agent.py +14 -0
  3. janito/agent/templates/profiles/system_prompt_template_Developer_with_Python_Tools.txt.j2 +59 -11
  4. janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +53 -7
  5. janito/agent/templates/profiles/system_prompt_template_market_analyst.txt.j2 +108 -8
  6. janito/agent/templates/profiles/system_prompt_template_model_conversation_without_tools_or_context.txt.j2 +53 -1
  7. janito/cli/chat_mode/session.py +8 -1
  8. janito/cli/chat_mode/shell/commands/__init__.py +2 -0
  9. janito/cli/chat_mode/shell/commands/security/__init__.py +1 -0
  10. janito/cli/chat_mode/shell/commands/security/allowed_sites.py +94 -0
  11. janito/cli/chat_mode/shell/commands/security_command.py +51 -0
  12. janito/cli/chat_mode/shell/commands.bak.zip +0 -0
  13. janito/cli/chat_mode/shell/session.bak.zip +0 -0
  14. janito/cli/cli_commands/list_plugins.py +45 -0
  15. janito/cli/cli_commands/show_system_prompt.py +13 -40
  16. janito/cli/core/getters.py +4 -0
  17. janito/cli/core/runner.py +7 -2
  18. janito/cli/core/setters.py +10 -1
  19. janito/cli/main_cli.py +25 -3
  20. janito/cli/single_shot_mode/handler.py +3 -1
  21. janito/config_manager.py +10 -0
  22. janito/docs/GETTING_STARTED.md +0 -0
  23. janito/drivers/dashscope.bak.zip +0 -0
  24. janito/drivers/openai/README.md +0 -0
  25. janito/drivers/openai_responses.bak.zip +0 -0
  26. janito/llm/README.md +0 -0
  27. janito/mkdocs.yml +0 -0
  28. janito/plugins/__init__.py +17 -0
  29. janito/plugins/base.py +93 -0
  30. janito/plugins/discovery.py +160 -0
  31. janito/plugins/manager.py +185 -0
  32. janito/providers/dashscope.bak.zip +0 -0
  33. janito/providers/ibm/README.md +0 -0
  34. janito/shell.bak.zip +0 -0
  35. janito/tools/DOCSTRING_STANDARD.txt +0 -0
  36. janito/tools/README.md +0 -0
  37. janito/tools/adapters/local/__init__.py +2 -0
  38. janito/tools/adapters/local/adapter.py +55 -0
  39. janito/tools/adapters/local/ask_user.py +2 -0
  40. janito/tools/adapters/local/fetch_url.py +89 -4
  41. janito/tools/adapters/local/find_files.py +2 -0
  42. janito/tools/adapters/local/get_file_outline/core.py +2 -0
  43. janito/tools/adapters/local/get_file_outline/search_outline.py +2 -0
  44. janito/tools/adapters/local/open_html_in_browser.py +2 -0
  45. janito/tools/adapters/local/open_url.py +2 -0
  46. janito/tools/adapters/local/python_code_run.py +15 -10
  47. janito/tools/adapters/local/python_command_run.py +14 -9
  48. janito/tools/adapters/local/python_file_run.py +15 -10
  49. janito/tools/adapters/local/read_chart.py +252 -0
  50. janito/tools/adapters/local/read_files.py +2 -0
  51. janito/tools/adapters/local/replace_text_in_file.py +1 -1
  52. janito/tools/adapters/local/run_bash_command.py +18 -12
  53. janito/tools/adapters/local/run_powershell_command.py +15 -9
  54. janito/tools/adapters/local/search_text/core.py +2 -0
  55. janito/tools/adapters/local/validate_file_syntax/core.py +6 -0
  56. janito/tools/adapters/local/validate_file_syntax/jinja2_validator.py +47 -0
  57. janito/tools/adapters/local/view_file.py +2 -0
  58. janito/tools/loop_protection.py +115 -0
  59. janito/tools/loop_protection_decorator.py +110 -0
  60. janito/tools/outline_file.bak.zip +0 -0
  61. janito/tools/url_whitelist.py +121 -0
  62. {janito-2.22.0.dist-info → janito-2.24.1.dist-info}/METADATA +411 -411
  63. {janito-2.22.0.dist-info → janito-2.24.1.dist-info}/RECORD +52 -39
  64. {janito-2.22.0.dist-info → janito-2.24.1.dist-info}/entry_points.txt +0 -0
  65. {janito-2.22.0.dist-info → janito-2.24.1.dist-info}/licenses/LICENSE +0 -0
  66. {janito-2.22.0.dist-info → janito-2.24.1.dist-info}/top_level.txt +0 -0
  67. {janito-2.22.0.dist-info → janito-2.24.1.dist-info}/WHEEL +0 -0
janito/README.md CHANGED
File without changes
@@ -144,6 +144,20 @@ def _prepare_template_context(role, profile, allowed_permissions):
144
144
  context["platform"] = pd.get_platform_name()
145
145
  context["python_version"] = pd.get_python_version()
146
146
  context["shell_info"] = pd.detect_shell()
147
+
148
+ # Add allowed sites for market analyst profile
149
+ if profile == "market-analyst":
150
+ from janito.tools.url_whitelist import get_url_whitelist_manager
151
+ whitelist_manager = get_url_whitelist_manager()
152
+ allowed_sites = whitelist_manager.get_allowed_sites()
153
+ context["allowed_sites"] = allowed_sites
154
+
155
+ # Add market data sources documentation
156
+ if not allowed_sites:
157
+ context["allowed_sites_info"] = "No whitelist restrictions - all sites allowed"
158
+ else:
159
+ context["allowed_sites_info"] = f"Restricted to: {', '.join(allowed_sites)}"
160
+
147
161
  return context
148
162
 
149
163
 
@@ -1,22 +1,70 @@
1
- {# General role setup
1
+ {# Profile Metadata #}
2
+ {% if name %}Name: {{ name }}{% endif %}
3
+ {% if version %}Version: {{ version }}{% endif %}
4
+ {% if description %}Description: {{ description }}{% endif %}
5
+ {% if author %}Author: {{ author }}{% endif %}
6
+ {% if tags %}Tags: {{ tags | join(', ') }}{% endif %}
7
+
8
+ {# General role setup
2
9
  ex. "Search in code" -> Python Developer -> find(*.py) | Java Developer -> find(*.java)
3
10
  #}
4
- You are: {{ role }}
11
+ You are: {{ role | default('developer') }}
5
12
 
6
- {# Improves tool selection and platform specific constrains, eg, path format, C:\ vs /path #}
7
- {% if allowed_permissions and 'x' in allowed_permissions %}
8
- You will be using the following environment:
9
- Platform: {{ platform }}
10
- Python version: {{ python_version }}
11
- Shell/Environment: {{ shell_info }}
13
+ {% if capabilities %}
14
+ ## Capabilities
15
+ {% for capability in capabilities %}
16
+ - {{ capability }}
17
+ {% endfor %}
18
+ {% else %}
19
+ ## Capabilities
20
+ - Software development and engineering
21
+ - Code analysis and debugging
22
+ - File system operations
23
+ - Python development and tooling
24
+ - Cross-platform development
12
25
  {% endif %}
13
26
 
27
+ {% if constraints %}
28
+ ## Constraints
29
+ {% for constraint in constraints %}
30
+ - {{ constraint }}
31
+ {% endfor %}
32
+ {% endif %}
14
33
 
15
- {% if allowed_permissions and 'r' in allowed_permissions %}
16
- Before answering map the questions to artifacts found in the current directory - the current project.
34
+ {% if environment or platform or python_version or shell_info %}
35
+ ## Environment
36
+ {% if platform %}Platform: {{ platform }}{% endif %}
37
+ {% if python_version %}Python version: {{ python_version }}{% endif %}
38
+ {% if shell_info %}Shell/Environment: {{ shell_info }}{% endif %}
39
+ {% endif %}
40
+
41
+ {% if examples %}
42
+ ## Examples
43
+ {% for example in examples %}
44
+ ### {{ example.title }}
45
+ {{ example.description }}
46
+ ```
47
+ {{ example.code }}
48
+ ```
49
+ {% endfor %}
50
+ {% endif %}
51
+
52
+ {% if custom_instructions %}
53
+ ## Custom Instructions
54
+ {{ custom_instructions }}
55
+ {% endif %}
56
+
57
+ {% if available_tools %}
58
+ ## Available Tools
59
+ {% for tool in available_tools %}
60
+ - **{{ tool.name }}**: {{ tool.description }}
61
+ {% if tool.parameters %}
62
+ Parameters: {{ tool.parameters | join(', ') }}
63
+ {% endif %}
64
+ {% endfor %}
17
65
  {% endif %}
18
66
 
19
- Respond according to the following guidelines:
67
+ ## Guidelines
20
68
  {% if allowed_permissions %}
21
69
  - Before using the namespace tools provide a short reason
22
70
  {% endif %}
@@ -1,14 +1,60 @@
1
- You are: software developer
1
+ {# Profile Metadata #}
2
+ {% if name %}Name: {{ name }}{% endif %}
3
+ {% if version %}Version: {{ version }}{% endif %}
4
+ {% if description %}Description: {{ description }}{% endif %}
5
+ {% if author %}Author: {{ author }}{% endif %}
6
+ {% if tags %}Tags: {{ tags | join(', ') }}{% endif %}
2
7
 
3
- {# Improves tool selection and platform specific constrains, eg, path format, C:\ vs /path #}
4
- You will be using the following environment:
5
- Platform: Windows
6
- Shell/Environment: PowerShell
8
+ You are: {{ role | default('software developer') }}
7
9
 
10
+ {% if capabilities %}
11
+ ## Capabilities
12
+ {% for capability in capabilities %}
13
+ - {{ capability }}
14
+ {% endfor %}
15
+ {% endif %}
16
+
17
+ {% if constraints %}
18
+ ## Constraints
19
+ {% for constraint in constraints %}
20
+ - {{ constraint }}
21
+ {% endfor %}
22
+ {% endif %}
8
23
 
9
- Before answering map the questions to artifacts found in the current directory - the current project.
24
+ {% if environment or platform or shell_info %}
25
+ ## Environment
26
+ {% if platform %}Platform: {{ platform }}{% endif %}
27
+ {% if python_version %}Python version: {{ python_version }}{% endif %}
28
+ {% if shell_info %}Shell/Environment: {{ shell_info }}{% endif %}
29
+ {% endif %}
30
+
31
+ {% if examples %}
32
+ ## Examples
33
+ {% for example in examples %}
34
+ ### {{ example.title }}
35
+ {{ example.description }}
36
+ ```
37
+ {{ example.code }}
38
+ ```
39
+ {% endfor %}
40
+ {% endif %}
41
+
42
+ {% if custom_instructions %}
43
+ ## Custom Instructions
44
+ {{ custom_instructions }}
45
+ {% endif %}
46
+
47
+ {% if available_tools %}
48
+ ## Available Tools
49
+ {% for tool in available_tools %}
50
+ - **{{ tool.name }}**: {{ tool.description }}
51
+ {% if tool.parameters %}
52
+ Parameters: {{ tool.parameters | join(', ') }}
53
+ {% endif %}
54
+ {% endfor %}
55
+ {% endif %}
10
56
 
11
- Respond according to the following guidelines:
57
+ ## Guidelines
12
58
  {% if allowed_permissions %}
13
59
  - Before using the namespace tools provide a short reason
14
60
  {% endif %}
@@ -1,10 +1,110 @@
1
- You are: market analyst specializing in financial markets, business intelligence, and economic research
1
+ {# Profile Metadata #}
2
+ {% if name %}Name: {{ name }}{% endif %}
3
+ {% if version %}Version: {{ version }}{% endif %}
4
+ {% if description %}Description: {{ description }}{% endif %}
5
+ {% if author %}Author: {{ author }}{% endif %}
6
+ {% if tags %}Tags: {{ tags | join(', ') }}{% endif %}
2
7
 
3
- Focus on providing market analysis, financial insights, and business intelligence. When analyzing data:
8
+ You are: {{ role | default('market analyst specializing in financial markets, business intelligence, and economic research') }}
4
9
 
5
- Identify market trends and patterns
6
- • Provide quantitative analysis with clear metrics
7
- Consider economic indicators and market sentiment
8
- Offer actionable insights for business decisions
9
- Use appropriate financial terminology and frameworks
10
- Reference relevant market data, benchmarks, and industry standards
10
+ {% if capabilities %}
11
+ ## Capabilities
12
+ {% for capability in capabilities %}
13
+ - {{ capability }}
14
+ {% endfor %}
15
+ {% else %}
16
+ ## Capabilities
17
+ - Financial analysis and market insights
18
+ - Stock recommendations and trading strategies
19
+ - Technical and fundamental analysis
20
+ - Risk management and position sizing
21
+ - Economic research and business intelligence
22
+ {% endif %}
23
+
24
+ {% if constraints %}
25
+ ## Constraints
26
+ {% for constraint in constraints %}
27
+ - {{ constraint }}
28
+ {% endfor %}
29
+ {% else %}
30
+ ## Constraints
31
+ - Only use allowed sites configured via security settings
32
+ - Never attempt to access unauthorized sources
33
+ - Provide actionable insights with specific entry/exit strategies
34
+ - Include risk management in all recommendations
35
+ {% endif %}
36
+
37
+ {% if data_sources %}
38
+ ## Data Sources
39
+ {% for source in data_sources %}
40
+ - {{ source }}
41
+ {% endfor %}
42
+ {% else %}
43
+ ## Data Sources
44
+ {% if allowed_sites %}
45
+ ✅ **Configured Sources:** {{ ', '.join(allowed_sites) }}
46
+ {% else %}
47
+ ⚠️ **No whitelist configured** - All sites allowed (use with caution)
48
+ {% endif %}
49
+
50
+ **Recommended Market Data Sources:**
51
+ - **Tier 1 (Government):** sec.gov, fred.stlouisfed.org
52
+ - **Tier 2 (Public):** tradingview.com, investing.com, finance.yahoo.com
53
+ - **Tier 3 (APIs):** alphavantage.co, financialmodelingprep.com, twelvedata.com
54
+ {% endif %}
55
+
56
+ {% if environment or platform or shell_info %}
57
+ ## Environment
58
+ {% if platform %}Platform: {{ platform }}{% endif %}
59
+ {% if python_version %}Python version: {{ python_version }}{% endif %}
60
+ {% if shell_info %}Shell/Environment: {{ shell_info }}{% endif %}
61
+ {% endif %}
62
+
63
+ {% if examples %}
64
+ ## Examples
65
+ {% for example in examples %}
66
+ ### {{ example.title }}
67
+ {{ example.description }}
68
+ ```
69
+ {{ example.code }}
70
+ ```
71
+ {% endfor %}
72
+ {% else %}
73
+ ## Analysis Framework
74
+
75
+ When analyzing data:
76
+
77
+ • Identify market trends and patterns with specific technical indicators (RSI, MACD, moving averages, support/resistance levels)
78
+ • Provide quantitative analysis with clear metrics, valuation ratios (P/E, P/S, EV/EBITDA), and financial ratios
79
+ • Consider economic indicators, market sentiment, and sector rotation patterns
80
+ • Offer actionable insights for trading and investment decisions with specific entry/exit strategies
81
+ • Use appropriate financial terminology and frameworks (DCF, comparable company analysis, technical analysis)
82
+ • Reference relevant market data, benchmarks, and industry standards
83
+ • Provide specific stock recommendations with risk management strategies and position sizing guidance
84
+ • Analyze options flow, institutional positioning, and sentiment indicators
85
+
86
+ When asked about specific stocks or market movements, provide detailed analysis including:
87
+ - Technical indicators and chart patterns
88
+ - Fundamental valuation metrics
89
+ - Analyst estimate revisions and sentiment shifts
90
+ - Options market activity and flow
91
+ - Risk/reward profiles for trades
92
+ - Specific price targets and stop-loss levels
93
+ {% endif %}
94
+
95
+ {% if custom_instructions %}
96
+ ## Custom Instructions
97
+ {{ custom_instructions }}
98
+ {% endif %}
99
+
100
+ {% if available_tools %}
101
+ ## Available Tools
102
+ {% for tool in available_tools %}
103
+ - **{{ tool.name }}**: {{ tool.description }}
104
+ {% if tool.parameters %}
105
+ Parameters: {{ tool.parameters | join(', ') }}
106
+ {% endif %}
107
+ {% endfor %}
108
+ {% endif %}
109
+
110
+ ## Guidelines
@@ -1 +1,53 @@
1
- You are a helpful assistant.
1
+ {# Profile Metadata #}
2
+ {% if name %}Name: {{ name }}{% endif %}
3
+ {% if version %}Version: {{ version }}{% endif %}
4
+ {% if description %}Description: {{ description }}{% endif %}
5
+ {% if author %}Author: {{ author }}{% endif %}
6
+ {% if tags %}Tags: {{ tags | join(', ') }}{% endif %}
7
+
8
+ You are: {{ role | default('helpful assistant') }}
9
+
10
+ {% if capabilities %}
11
+ ## Capabilities
12
+ {% for capability in capabilities %}
13
+ - {{ capability }}
14
+ {% endfor %}
15
+ {% endif %}
16
+
17
+ {% if constraints %}
18
+ ## Constraints
19
+ {% for constraint in constraints %}
20
+ - {{ constraint }}
21
+ {% endfor %}
22
+ {% endif %}
23
+
24
+ {% if examples %}
25
+ ## Examples
26
+ {% for example in examples %}
27
+ ### {{ example.title }}
28
+ {{ example.description }}
29
+ ```
30
+ {{ example.code }}
31
+ ```
32
+ {% endfor %}
33
+ {% endif %}
34
+
35
+ {% if custom_instructions %}
36
+ ## Custom Instructions
37
+ {{ custom_instructions }}
38
+ {% endif %}
39
+
40
+ {% if available_tools %}
41
+ ## Available Tools
42
+ {% for tool in available_tools %}
43
+ - **{{ tool.name }}**: {{ tool.description }}
44
+ {% if tool.parameters %}
45
+ Parameters: {{ tool.parameters | join(', ') }}
46
+ {% endif %}
47
+ {% endfor %}
48
+ {% endif %}
49
+
50
+ ## Guidelines
51
+ - Provide helpful, accurate, and concise responses
52
+ - Ask clarifying questions when needed
53
+ - Maintain a friendly and professional tone
@@ -94,6 +94,7 @@ class ChatSession:
94
94
  profile_system_prompt,
95
95
  conversation_history,
96
96
  )
97
+ self.profile = profile # Store profile name for welcome message
97
98
  self.shell_state = ChatShellState(self.mem_history, conversation_history)
98
99
  self.shell_state.agent = self.agent
99
100
  # Set no_tools_mode if present
@@ -116,6 +117,7 @@ class ChatSession:
116
117
  profile = getattr(args, "profile", None) if args is not None else None
117
118
  role_arg = getattr(args, "role", None) if args is not None else None
118
119
  python_profile = getattr(args, "python", False) if args is not None else False
120
+ market_profile = getattr(args, "market", False) if args is not None else False
119
121
  profile_system_prompt = None
120
122
  no_tools_mode = False
121
123
 
@@ -123,7 +125,11 @@ class ChatSession:
123
125
  if python_profile and profile is None and role_arg is None:
124
126
  profile = "Developer with Python Tools"
125
127
 
126
- if profile is None and role_arg is None and not python_profile:
128
+ # Handle --market flag
129
+ if market_profile and profile is None and role_arg is None:
130
+ profile = "Market Analyst"
131
+
132
+ if profile is None and role_arg is None and not python_profile and not market_profile:
127
133
  try:
128
134
  from janito.cli.chat_mode.session_profile_select import select_profile
129
135
 
@@ -202,6 +208,7 @@ class ChatSession:
202
208
  from janito import __version__
203
209
 
204
210
  self.console.print(f"[bold green]Janito Chat Mode v{__version__}[/bold green]")
211
+ self.console.print(f"[dim]Profile: {self.profile}[/dim]")
205
212
  self.console.print(
206
213
  "[green]/help for commands /exit or Ctrl+C to quit[/green]"
207
214
  )
@@ -9,6 +9,7 @@ from .role import RoleCommandShellHandler
9
9
  from .session import HistoryShellHandler
10
10
  from .tools import ToolsShellHandler
11
11
  from .help import HelpShellHandler
12
+ from .security_command import SecurityCommand
12
13
  from janito.cli.console import shared_console
13
14
 
14
15
  COMMAND_HANDLERS = {
@@ -41,6 +42,7 @@ COMMAND_HANDLERS = {
41
42
  "/model": ModelShellHandler,
42
43
  "/multi": MultiShellHandler,
43
44
  "/help": HelpShellHandler,
45
+ "/security": SecurityCommand,
44
46
  }
45
47
 
46
48
 
@@ -0,0 +1 @@
1
+ """Security management commands for chat mode."""
@@ -0,0 +1,94 @@
1
+ """Security commands for managing allowed sites."""
2
+
3
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler as BaseCommand
4
+ from janito.tools.url_whitelist import get_url_whitelist_manager
5
+
6
+
7
+ class SecurityAllowedSitesCommand(BaseCommand):
8
+ """Manage allowed sites for fetch_url tool."""
9
+
10
+ def get_name(self) -> str:
11
+ return "allowed-sites"
12
+
13
+ def get_description(self) -> str:
14
+ return "Manage allowed sites for the fetch_url tool"
15
+
16
+ def get_usage(self):
17
+ return self.get_description() + """
18
+ Usage: /security allowed-sites [command] [site]
19
+
20
+ Commands:
21
+ list List all allowed sites
22
+ add <site> Add a site to the whitelist
23
+ remove <site> Remove a site from the whitelist
24
+ clear Clear all allowed sites (allow all)
25
+
26
+ Examples:
27
+ /security allowed-sites list
28
+ /security allowed-sites add tradingview.com
29
+ /security allowed-sites remove yahoo.com
30
+ /security allowed-sites clear
31
+ """
32
+ return """
33
+ Usage: /security allowed-sites [command] [site]
34
+
35
+ Commands:
36
+ list List all allowed sites
37
+ add <site> Add a site to the whitelist
38
+ remove <site> Remove a site from the whitelist
39
+ clear Clear all allowed sites (allow all)
40
+
41
+ Examples:
42
+ /security allowed-sites list
43
+ /security allowed-sites add tradingview.com
44
+ /security allowed-sites remove yahoo.com
45
+ /security allowed-sites clear
46
+ """
47
+
48
+ def run(self):
49
+ """Execute the allowed-sites command."""
50
+ args = self.after_cmd_line.strip().split()
51
+
52
+ if not args:
53
+ print(self.get_usage())
54
+ return
55
+
56
+ command = args[0].lower()
57
+ whitelist_manager = get_url_whitelist_manager()
58
+
59
+ if command == "list":
60
+ sites = whitelist_manager.get_allowed_sites()
61
+ if sites:
62
+ print("Allowed sites:")
63
+ for site in sites:
64
+ print(f" • {site}")
65
+ else:
66
+ print("No sites are whitelisted (all sites are allowed)")
67
+
68
+ elif command == "add":
69
+ if len(args) < 2:
70
+ print("Error: Please specify a site to add")
71
+ return
72
+ site = args[1]
73
+ if whitelist_manager.add_allowed_site(site):
74
+ print(f"✅ Added '{site}' to allowed sites")
75
+ else:
76
+ print(f"ℹ️ '{site}' is already in allowed sites")
77
+
78
+ elif command == "remove":
79
+ if len(args) < 2:
80
+ print("Error: Please specify a site to remove")
81
+ return
82
+ site = args[1]
83
+ if whitelist_manager.remove_allowed_site(site):
84
+ print(f"✅ Removed '{site}' from allowed sites")
85
+ else:
86
+ print(f"ℹ️ '{site}' was not in allowed sites")
87
+
88
+ elif command == "clear":
89
+ whitelist_manager.clear_whitelist()
90
+ print("✅ Cleared all allowed sites (all sites are now allowed)")
91
+
92
+ else:
93
+ print(f"Error: Unknown command '{command}'")
94
+ print(self.get_usage())
@@ -0,0 +1,51 @@
1
+ """Security command group for chat mode."""
2
+
3
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler as BaseCommand
4
+ from janito.cli.chat_mode.shell.commands.security.allowed_sites import SecurityAllowedSitesCommand
5
+
6
+
7
+ class SecurityCommand(BaseCommand):
8
+ """Security management command group."""
9
+
10
+ def get_name(self) -> str:
11
+ return "security"
12
+
13
+ def get_description(self) -> str:
14
+ return "Security management commands"
15
+
16
+ def get_usage(self):
17
+ return """
18
+ Usage: /security <subcommand> [args...]
19
+
20
+ Subcommands:
21
+ allowed-sites Manage allowed sites for fetch_url tool
22
+
23
+ Examples:
24
+ /security allowed-sites list
25
+ /security allowed-sites add tradingview.com
26
+ /security allowed-sites remove yahoo.com
27
+ """
28
+
29
+ def __init__(self, after_cmd_line=None, shell_state=None):
30
+ super().__init__(after_cmd_line=after_cmd_line, shell_state=shell_state)
31
+ self.subcommands = {
32
+ "allowed-sites": SecurityAllowedSitesCommand(after_cmd_line=after_cmd_line, shell_state=shell_state)
33
+ }
34
+
35
+ def run(self):
36
+ """Execute the security command."""
37
+ args = self.after_cmd_line.strip().split()
38
+
39
+ if not args:
40
+ print(self.get_usage())
41
+ return
42
+
43
+ subcommand = args[0].lower()
44
+ if subcommand in self.subcommands:
45
+ # Pass the remaining args to the subcommand
46
+ remaining_args = " ".join(args[1:]) if len(args) > 1 else ""
47
+ self.subcommands[subcommand].after_cmd_line = remaining_args
48
+ self.subcommands[subcommand].run()
49
+ else:
50
+ print(f"Error: Unknown security subcommand '{subcommand}'")
51
+ print(self.get_usage())
File without changes
File without changes
@@ -0,0 +1,45 @@
1
+ """
2
+ CLI command to list available and loaded plugins.
3
+ """
4
+
5
+ import argparse
6
+ from typing import List, Dict, Any
7
+ from janito.plugins.discovery import list_available_plugins, discover_plugins
8
+ import os
9
+ from janito.plugins.manager import PluginManager
10
+
11
+
12
+ def handle_list_plugins(args: argparse.Namespace) -> None:
13
+ """List plugins command handler."""
14
+
15
+ if getattr(args, 'list_plugins_available', False):
16
+ # List available plugins
17
+ available = list_available_plugins()
18
+ if available:
19
+ print("Available plugins:")
20
+ for plugin in available:
21
+ print(f" - {plugin}")
22
+ else:
23
+ print("No plugins found in search paths")
24
+ print("Search paths:")
25
+ print(f" - {os.getcwd()}/plugins")
26
+ print(f" - {os.path.expanduser('~')}/.janito/plugins")
27
+ else:
28
+ # List loaded plugins
29
+ manager = PluginManager()
30
+ loaded = manager.list_plugins()
31
+
32
+ if loaded:
33
+ print("Loaded plugins:")
34
+ for plugin_name in loaded:
35
+ metadata = manager.get_plugin_metadata(plugin_name)
36
+ if metadata:
37
+ print(f" - {metadata.name} v{metadata.version}")
38
+ print(f" {metadata.description}")
39
+ if metadata.author:
40
+ print(f" Author: {metadata.author}")
41
+ print()
42
+ else:
43
+ print("No plugins loaded")
44
+
45
+
@@ -9,6 +9,7 @@ from janito.platform_discovery import PlatformDiscovery
9
9
  from pathlib import Path
10
10
  from jinja2 import Template
11
11
  import importlib.resources
12
+ import importlib.resources as resources
12
13
  import re
13
14
 
14
15
 
@@ -115,6 +116,11 @@ def handle_show_system_prompt(args):
115
116
  Path(__file__).parent.parent.parent / "agent" / "templates" / "profiles"
116
117
  )
117
118
  profile = getattr(args, "profile", None)
119
+
120
+ # Handle --market flag mapping to Market Analyst profile
121
+ if profile is None and getattr(args, "market", False):
122
+ profile = "Market Analyst"
123
+
118
124
  if not profile:
119
125
  print(
120
126
  "[janito] No profile specified. The main agent runs without a system prompt template.\n"
@@ -126,46 +132,13 @@ def handle_show_system_prompt(args):
126
132
  _print_debug_info(debug_flag, template_filename, allowed_permissions, context)
127
133
 
128
134
  if not template_content:
129
- if profile:
130
- from janito.cli.cli_commands.list_profiles import _gather_default_profiles, _gather_user_profiles
131
- import re
132
-
133
- default_profiles = _gather_default_profiles()
134
- user_profiles = _gather_user_profiles()
135
-
136
- available_profiles = []
137
- if default_profiles:
138
- available_profiles.extend([(p, "default") for p in default_profiles])
139
- if user_profiles:
140
- available_profiles.extend([(p, "user") for p in user_profiles])
141
-
142
- # Normalize the input profile for better matching suggestions
143
- normalized_input = re.sub(r"\s+", " ", profile.strip().lower())
144
-
145
- if available_profiles:
146
- profile_list = "\n".join([f" - {name} ({source})" for name, source in available_profiles])
147
-
148
- # Find close matches
149
- close_matches = []
150
- for name, source in available_profiles:
151
- normalized_name = name.lower()
152
- if normalized_input in normalized_name or normalized_name in normalized_input:
153
- close_matches.append(name)
154
-
155
- suggestion = ""
156
- if close_matches:
157
- suggestion = f"\nDid you mean: {', '.join(close_matches)}?"
158
-
159
- error_msg = f"[janito] Could not find profile '{profile}'. Available profiles:\n{profile_list}{suggestion}"
160
- else:
161
- error_msg = f"[janito] Could not find profile '{profile}'. No profiles available."
162
-
163
- raise FileNotFoundError(error_msg)
164
- else:
165
- print(
166
- f"[janito] Could not find {template_filename} in {templates_dir / template_filename} nor in janito.agent.templates.profiles package."
167
- )
168
- print("No system prompt is set or resolved for this configuration.")
135
+ # Try to load directly from package resources as fallback
136
+ try:
137
+ template_content = resources.files("janito.agent.templates.profiles").joinpath(
138
+ f"system_prompt_template_{profile.lower().replace(' ', '_')}.txt.j2"
139
+ ).read_text(encoding="utf-8")
140
+ except (FileNotFoundError, ModuleNotFoundError, AttributeError):
141
+ print(f"[janito] Could not find profile '{profile}'. This may be a configuration issue.")
169
142
  return
170
143
 
171
144
  template = Template(template_content)