janito 0.14.0__py3-none-any.whl → 1.0.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.
Files changed (98) hide show
  1. janito/__init__.py +1 -5
  2. janito/__main__.py +3 -5
  3. janito/agent/__init__.py +1 -0
  4. janito/agent/agent.py +96 -0
  5. janito/agent/config.py +113 -0
  6. janito/agent/config_defaults.py +10 -0
  7. janito/agent/conversation.py +107 -0
  8. janito/agent/queued_tool_handler.py +16 -0
  9. janito/agent/runtime_config.py +30 -0
  10. janito/agent/tool_handler.py +124 -0
  11. janito/agent/tools/__init__.py +11 -0
  12. janito/agent/tools/ask_user.py +63 -0
  13. janito/agent/tools/bash_exec.py +58 -0
  14. janito/agent/tools/create_directory.py +19 -0
  15. janito/agent/tools/create_file.py +43 -0
  16. janito/agent/tools/fetch_url.py +48 -0
  17. janito/agent/tools/file_str_replace.py +48 -0
  18. janito/agent/tools/find_files.py +37 -0
  19. janito/agent/tools/gitignore_utils.py +40 -0
  20. janito/agent/tools/move_file.py +37 -0
  21. janito/agent/tools/remove_file.py +19 -0
  22. janito/agent/tools/rich_live.py +37 -0
  23. janito/agent/tools/rich_utils.py +31 -0
  24. janito/agent/tools/search_text.py +41 -0
  25. janito/agent/tools/view_file.py +34 -0
  26. janito/cli/__init__.py +0 -6
  27. janito/cli/_print_config.py +68 -0
  28. janito/cli/_utils.py +8 -0
  29. janito/cli/arg_parser.py +26 -0
  30. janito/cli/config_commands.py +131 -0
  31. janito/cli/logging_setup.py +27 -0
  32. janito/cli/main.py +39 -0
  33. janito/cli/runner.py +135 -0
  34. janito/cli_chat_shell/__init__.py +1 -0
  35. janito/cli_chat_shell/chat_loop.py +147 -0
  36. janito/cli_chat_shell/commands.py +202 -0
  37. janito/cli_chat_shell/config_shell.py +75 -0
  38. janito/cli_chat_shell/load_prompt.py +15 -0
  39. janito/cli_chat_shell/session_manager.py +60 -0
  40. janito/cli_chat_shell/ui.py +136 -0
  41. janito/render_prompt.py +12 -0
  42. janito/templates/system_instructions.j2 +36 -0
  43. janito/web/__init__.py +0 -0
  44. janito/web/__main__.py +17 -0
  45. janito/web/app.py +132 -0
  46. janito-1.0.0.dist-info/METADATA +144 -0
  47. janito-1.0.0.dist-info/RECORD +51 -0
  48. {janito-0.14.0.dist-info → janito-1.0.0.dist-info}/WHEEL +2 -1
  49. janito-1.0.0.dist-info/entry_points.txt +2 -0
  50. {janito-0.14.0.dist-info → janito-1.0.0.dist-info}/licenses/LICENSE +2 -2
  51. janito-1.0.0.dist-info/top_level.txt +1 -0
  52. janito/callbacks.py +0 -34
  53. janito/cli/agent/__init__.py +0 -7
  54. janito/cli/agent/conversation.py +0 -149
  55. janito/cli/agent/initialization.py +0 -172
  56. janito/cli/agent/query.py +0 -108
  57. janito/cli/agent.py +0 -12
  58. janito/cli/app.py +0 -182
  59. janito/cli/commands/__init__.py +0 -12
  60. janito/cli/commands/config.py +0 -242
  61. janito/cli/commands/history.py +0 -119
  62. janito/cli/commands/profile.py +0 -72
  63. janito/cli/commands/validation.py +0 -24
  64. janito/cli/commands/workspace.py +0 -31
  65. janito/cli/commands.py +0 -12
  66. janito/cli/output.py +0 -29
  67. janito/cli/utils.py +0 -22
  68. janito/config.py +0 -375
  69. janito/data/instructions_template.txt +0 -31
  70. janito/token_report.py +0 -154
  71. janito/tools/__init__.py +0 -44
  72. janito/tools/bash/bash.py +0 -84
  73. janito/tools/bash/unix_persistent_bash.py +0 -184
  74. janito/tools/bash/win_persistent_bash.py +0 -308
  75. janito/tools/decorators.py +0 -90
  76. janito/tools/delete_file.py +0 -65
  77. janito/tools/fetch_webpage/__init__.py +0 -23
  78. janito/tools/fetch_webpage/core.py +0 -182
  79. janito/tools/find_files.py +0 -220
  80. janito/tools/move_file.py +0 -72
  81. janito/tools/prompt_user.py +0 -57
  82. janito/tools/replace_file.py +0 -63
  83. janito/tools/rich_console.py +0 -176
  84. janito/tools/search_text.py +0 -226
  85. janito/tools/str_replace_editor/__init__.py +0 -6
  86. janito/tools/str_replace_editor/editor.py +0 -55
  87. janito/tools/str_replace_editor/handlers/__init__.py +0 -16
  88. janito/tools/str_replace_editor/handlers/create.py +0 -60
  89. janito/tools/str_replace_editor/handlers/insert.py +0 -100
  90. janito/tools/str_replace_editor/handlers/str_replace.py +0 -94
  91. janito/tools/str_replace_editor/handlers/undo.py +0 -64
  92. janito/tools/str_replace_editor/handlers/view.py +0 -159
  93. janito/tools/str_replace_editor/utils.py +0 -33
  94. janito/tools/think.py +0 -37
  95. janito/tools/usage_tracker.py +0 -137
  96. janito-0.14.0.dist-info/METADATA +0 -396
  97. janito-0.14.0.dist-info/RECORD +0 -53
  98. janito-0.14.0.dist-info/entry_points.txt +0 -2
janito/cli/app.py DELETED
@@ -1,182 +0,0 @@
1
- """
2
- Main CLI application for Janito.
3
- """
4
- import sys
5
- from typing import Optional
6
- import typer
7
- from rich.console import Console
8
- import importlib.metadata
9
-
10
- from janito import __version__
11
- from janito.config import get_config
12
- from janito.cli.commands import handle_config_commands, validate_parameters
13
- from janito.cli.agent import handle_query
14
- from janito.cli.utils import get_stdin_termination_hint
15
-
16
- app = typer.Typer()
17
- console = Console()
18
-
19
- @app.callback(invoke_without_command=True)
20
- def main(ctx: typer.Context,
21
- query: Optional[str] = typer.Argument(None, help="Query to send to the claudine agent"),
22
- verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose mode with detailed output"),
23
- show_tokens: bool = typer.Option(False, "--show-tokens", "--tokens", help="Show detailed token usage and pricing information"),
24
- workspace: Optional[str] = typer.Option(None, "--workspace", "-w", help="Set the workspace directory"),
25
- config_str: Optional[str] = typer.Option(None, "--set-config", help="Configuration string in format 'key=value', e.g., 'temperature=0.7' or 'profile=technical'"),
26
- show_config: bool = typer.Option(False, "--show-config", help="Show current configuration"),
27
- reset_config: bool = typer.Option(False, "--reset-config", help="Reset configuration by removing the config file"),
28
- set_api_key: Optional[str] = typer.Option(None, "--set-api-key", help="Set the Anthropic API key globally in the user's home directory"),
29
- ask: bool = typer.Option(False, "--ask", help="Enable ask mode which disables tools that perform changes"),
30
- trust: bool = typer.Option(False, "--trust", "-t", help="Enable trust mode which suppresses tool outputs for a more concise execution"),
31
- no_tools: bool = typer.Option(False, "--no-tools", help="Disable all tools for this session (per-session setting, not saved to config)"),
32
- temperature: float = typer.Option(0.0, "--temperature", help="Set the temperature for model generation (0.0 to 1.0)"),
33
- profile: Optional[str] = typer.Option(None, "--profile", help="Use a predefined parameter profile (precise, balanced, conversational, creative, technical)"),
34
- role: Optional[str] = typer.Option(None, "--role", help="Set the assistant's role (default: 'software engineer')"),
35
- system: Optional[str] = typer.Option(None, "--system", "-s", help="Provide custom system instructions, bypassing the default file load method"),
36
- version: bool = typer.Option(False, "--version", help="Show the version and exit"),
37
- continue_id: Optional[str] = typer.Option(None, "--continue-id", help="Continue a specific conversation with the given ID"),
38
- continue_flag: Optional[str] = typer.Option(None, "--continue", "-c", help="Continue a conversation. Can be used as: 1) --continue (to continue most recent), 2) --continue 123 (to continue conversation with ID 123), or 3) --continue \"query\" (to continue most recent with new query)"),
39
- history_flag: bool = typer.Option(False, "--history", help="Show a summary of conversations. Use --history for default (20) or --history n to specify count")):
40
- """
41
- Janito CLI tool. If a query is provided without a command, it will be sent to the claudine agent.
42
- """
43
- # Set verbose mode in config
44
- get_config().verbose = verbose
45
-
46
- # Set ask mode in config
47
- get_config().ask_mode = ask
48
-
49
- # Set trust mode in config
50
- get_config().trust_mode = trust
51
-
52
- # Set no-tools mode in config
53
- get_config().no_tools = no_tools
54
-
55
- # Show a message if ask mode is enabled
56
- if ask:
57
- console.print("[bold yellow]⚠️ Ask Mode enabled:[/bold yellow] 🔒 Tools that perform changes are disabled")
58
-
59
- # Show a message if trust mode is enabled
60
- if trust:
61
- console.print("[bold blue]⚡ Trust Mode enabled:[/bold blue] Tool outputs are suppressed for concise execution")
62
-
63
- # Show a message if no-tools mode is enabled
64
- if no_tools:
65
- console.print("[bold magenta]🚫 No-Tools Mode enabled:[/bold magenta] All tools are disabled for this session")
66
-
67
- # Show version and exit if requested
68
- if version:
69
- console.print(f"🚀 Janito version: {__version__}")
70
- sys.exit(0)
71
-
72
- # Validate temperature
73
- validate_parameters(temperature)
74
-
75
- # Process continue flags before handling other options
76
- continue_conversation = None
77
-
78
- # First, parse continue_flag and continue_id from original sys.argv to avoid typer issues
79
- # This is necessary because typer has trouble with quotes in some edge cases
80
- try:
81
- # Check if --continue or -c is in sys.argv
82
- args = sys.argv
83
-
84
- # Handle the --history flag with optional count parameter
85
- history_count_override = None
86
- if "--history" in args:
87
- history_idx = args.index("--history")
88
- history_flag = True
89
-
90
- # Check if there's a number after --history and it's not another flag
91
- if history_idx + 1 < len(args) and not args[history_idx + 1].startswith("-"):
92
- try:
93
- # Try to convert to int - if successful, it's a count
94
- history_count_override = int(args[history_idx + 1])
95
- except ValueError:
96
- # Not a number, ignore it
97
- pass
98
-
99
- if "--continue" in args or "-c" in args:
100
- continue_idx = args.index("--continue") if "--continue" in args else args.index("-c")
101
-
102
- # Check if there's at least one argument after --continue
103
- if continue_idx + 1 < len(args) and not args[continue_idx + 1].startswith("-"):
104
- # If next arg doesn't start with "-", it's our continue value
105
- continue_value = args[continue_idx + 1]
106
-
107
- # Check if continue_value is a numeric ID or a query
108
- if continue_value.isdigit():
109
- # It's an ID
110
- continue_conversation = continue_value
111
-
112
- # Check if there's a query after the ID
113
- if continue_idx + 2 < len(args) and not args[continue_idx + 2].startswith("-"):
114
- query = args[continue_idx + 2]
115
- else:
116
- # It's a query string for the most recent conversation
117
- continue_conversation = "" # Empty string means continue most recent
118
- query = continue_value
119
-
120
- if verbose:
121
- console.print(f"[bold blue]🔄 Continuing most recent conversation[/bold blue]")
122
- console.print(f"[dim]📝 Query: {query}[/dim]")
123
- else:
124
- # --continue with no args means continue most recent conversation
125
- continue_conversation = ""
126
-
127
- # Handle explicit --continue-id if specified (this takes precedence)
128
- if "--continue-id" in args:
129
- continue_id_idx = args.index("--continue-id")
130
- if continue_id_idx + 1 < len(args) and not args[continue_id_idx + 1].startswith("-"):
131
- continue_conversation = args[continue_id_idx + 1]
132
- except Exception as e:
133
- if verbose:
134
- console.print(f"[bold yellow]⚠️ Error parsing continue arguments: {str(e)}[/bold yellow]")
135
-
136
- # Fall back to typer-processed args if our parsing failed
137
- if continue_conversation is None:
138
- # Handle the --continue-id option
139
- if continue_id is not None:
140
- continue_conversation = continue_id
141
- # Handle the --continue flag option (processed by typer)
142
- elif continue_flag is not None:
143
- if continue_flag == "":
144
- continue_conversation = "" # Empty string means continue most recent
145
- elif continue_flag.isdigit():
146
- continue_conversation = continue_flag
147
- else:
148
- continue_conversation = "" # Empty string means continue most recent
149
- query = continue_flag # Use the continue_flag as the query
150
-
151
- # Handle configuration-related commands
152
- exit_after_config = handle_config_commands(
153
- ctx,
154
- reset_config,
155
- workspace,
156
- show_config,
157
- profile,
158
- role,
159
- set_api_key,
160
- config_str,
161
- query,
162
- continue_id,
163
- continue_flag,
164
- history_flag,
165
- history_count_override
166
- )
167
-
168
- if exit_after_config:
169
- sys.exit(0)
170
-
171
- # Handle query if no subcommand was invoked
172
- if ctx.invoked_subcommand is None:
173
- # If no query provided in command line, read from stdin
174
- # Only prompt for stdin if query is still None after processing --continue flag
175
- if not query:
176
- console.print("[bold blue]📝 No query provided in command line. Reading from stdin...[/bold blue]")
177
- console.print(get_stdin_termination_hint())
178
- query = sys.stdin.read().strip()
179
-
180
- # Only proceed if we have a query (either from command line or stdin)
181
- if query:
182
- handle_query(query, temperature, verbose, show_tokens, continue_conversation, system)
@@ -1,12 +0,0 @@
1
- """
2
- Command handling logic for Janito CLI.
3
- """
4
- from janito.cli.commands.config import handle_config_commands
5
- from janito.cli.commands.validation import validate_parameters
6
- from janito.cli.commands.history import handle_history
7
-
8
- __all__ = [
9
- "handle_config_commands",
10
- "validate_parameters",
11
- "handle_history",
12
- ]
@@ -1,242 +0,0 @@
1
- """
2
- Configuration management functions for Janito CLI.
3
- """
4
- import sys
5
- import os
6
- from pathlib import Path
7
- from typing import Optional
8
- import typer
9
- from rich.console import Console
10
-
11
- from janito.config import get_config, Config
12
- from janito.cli.commands.workspace import handle_workspace
13
- from janito.cli.commands.profile import handle_profile, handle_role
14
- from janito.cli.commands.history import handle_history
15
-
16
- console = Console()
17
-
18
- def handle_reset_config(reset_config: bool, ctx: typer.Context, query: Optional[str]) -> bool:
19
- """
20
- Handle the --reset-config parameter.
21
-
22
- Args:
23
- reset_config: Whether to reset the configuration
24
- ctx: Typer context
25
- query: Query string
26
-
27
- Returns:
28
- bool: True if the program should exit after this operation
29
- """
30
- if reset_config:
31
- try:
32
- config_path = Path(get_config().workspace_dir) / ".janito" / "config.json"
33
- if get_config().reset_config():
34
- console.print(f"[bold green]✅ Configuration file removed: {config_path}[/bold green]")
35
- else:
36
- console.print(f"[bold yellow]⚠️ Configuration file does not exist: {config_path}[/bold yellow]")
37
- except Exception as e:
38
- console.print(f"[bold red]Error removing configuration file:[/bold red] {str(e)}")
39
-
40
- # Exit after resetting config if no other operation is requested
41
- return ctx.invoked_subcommand is None and not query
42
-
43
- return False
44
-
45
- def handle_show_config(show_config: bool, ctx: typer.Context, query: Optional[str]) -> bool:
46
- """
47
- Handle the --show-config parameter.
48
-
49
- Args:
50
- show_config: Whether to show the configuration
51
- ctx: Typer context
52
- query: Query string
53
-
54
- Returns:
55
- bool: True if the program should exit after this operation
56
- """
57
- if show_config:
58
- config = get_config()
59
- console.print("[bold blue]⚙️ Current Configuration:[/bold blue]")
60
- console.print(f"[bold]📁 Local Configuration File:[/bold] .janito/config.json")
61
- console.print(f"[bold]🏠 Global Configuration File:[/bold] {Path.home() / '.janito' / 'config.json'}")
62
-
63
- # Show API key status
64
- api_key_global = Config.get_api_key()
65
- api_key_env = os.environ.get("ANTHROPIC_API_KEY")
66
- if api_key_global:
67
- console.print(f"[bold]🔑 API Key:[/bold] [green]Set in global config[/green]")
68
- elif api_key_env:
69
- console.print(f"[bold]🔑 API Key:[/bold] [yellow]Set in environment variable[/yellow]")
70
- else:
71
- console.print(f"[bold]🔑 API Key:[/bold] [red]Not set[/red]")
72
-
73
- console.print(f"[bold]🔊 Verbose Mode:[/bold] {'Enabled' if config.verbose else 'Disabled'}")
74
- console.print(f"[bold]❓ Ask Mode:[/bold] {'Enabled' if config.ask_mode else 'Disabled'}")
75
-
76
- console.print(f"[bold]👤 Role:[/bold] {config.role}")
77
-
78
- # Show profile information if one is set
79
- if config.profile:
80
- profile_data = config.get_available_profiles()[config.profile]
81
- console.print(f"[bold]📋 Active Profile:[/bold] {config.profile} - {profile_data['description']}")
82
-
83
- # Show available profiles
84
- profiles = config.get_available_profiles()
85
- if profiles:
86
- console.print("\n[bold blue]📋 Available Parameter Profiles:[/bold blue]")
87
- for name, data in profiles.items():
88
- console.print(f"[bold]🔹 {name}[/bold] - {data['description']}")
89
-
90
- # Exit if this was the only operation requested
91
- return ctx.invoked_subcommand is None and not query
92
-
93
- return False
94
-
95
- def handle_set_api_key(set_api_key: Optional[str], ctx: typer.Context, query: Optional[str]) -> bool:
96
- """
97
- Handle the --set-api-key parameter.
98
-
99
- Args:
100
- set_api_key: API key
101
- ctx: Typer context
102
- query: Query string
103
-
104
- Returns:
105
- bool: True if the program should exit after this operation
106
- """
107
- if set_api_key is not None:
108
- try:
109
- Config.set_api_key(set_api_key)
110
- console.print(f"[bold green]✅ API key saved to global configuration[/bold green]")
111
- console.print(f"[dim]📁 Location: {Path.home() / '.janito' / 'config.json'}[/dim]")
112
-
113
- # Exit after setting API key if no other operation is requested
114
- return ctx.invoked_subcommand is None and not query
115
- except Exception as e:
116
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
117
- sys.exit(1)
118
-
119
- return False
120
-
121
- def handle_set_config(config_str: Optional[str], ctx: typer.Context, query: Optional[str]) -> bool:
122
- """
123
- Handle the --set-config parameter.
124
-
125
- Args:
126
- config_str: Configuration string in format 'key=value'
127
- ctx: Typer context
128
- query: Query string
129
-
130
- Returns:
131
- bool: True if the program should exit after this operation
132
- """
133
- if config_str is not None:
134
- try:
135
- # Parse the config string
136
- config_parts = config_str.split("=", 1)
137
- if len(config_parts) != 2:
138
- console.print(f"[bold red]Error:[/bold red] Invalid configuration format. Use 'key=value' format.")
139
- return ctx.invoked_subcommand is None and not query
140
-
141
- key = config_parts[0].strip()
142
- value = config_parts[1].strip()
143
-
144
- # Remove quotes if present
145
- if (value.startswith("'") and value.endswith("'")) or \
146
- (value.startswith('"') and value.endswith('"')):
147
- value = value[1:-1]
148
-
149
- if key == "profile":
150
- try:
151
- get_config().set_profile(value)
152
- profile_data = get_config().get_available_profiles()[value.lower()]
153
- console.print(f"[bold green]✅ Profile set to '{value.lower()}'[/bold green]")
154
- console.print(f"[dim]📝 Description: {profile_data['description']}[/dim]")
155
- except ValueError as e:
156
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
157
- elif key == "temperature":
158
- try:
159
- temp_value = float(value)
160
- if temp_value < 0.0 or temp_value > 1.0:
161
- console.print("[bold red]Error:[/bold red] Temperature must be between 0.0 and 1.0")
162
- return ctx.invoked_subcommand is None and not query
163
-
164
- get_config().temperature = temp_value
165
- console.print(f"[bold green]✅ Temperature set to {temp_value} and saved to configuration[/bold green]")
166
- except ValueError:
167
- console.print(f"[bold red]Error:[/bold red] Invalid temperature value: {value}. Must be a float between 0.0 and 1.0.")
168
- # top_k and top_p are now only accessible through profiles
169
- elif key == "role":
170
- get_config().role = value
171
- console.print(f"[bold green]✅ Role set to '{value}' and saved to configuration[/bold green]")
172
- else:
173
- console.print(f"[bold yellow]Warning:[/bold yellow] Unsupported configuration key: {key}")
174
-
175
- # Exit after applying config changes if no other operation is requested
176
- return ctx.invoked_subcommand is None and not query
177
- except Exception as e:
178
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
179
-
180
- return False
181
-
182
- def handle_config_commands(
183
- ctx: typer.Context,
184
- reset_config: bool,
185
- workspace: Optional[str],
186
- show_config: bool,
187
- profile: Optional[str],
188
- role: Optional[str],
189
- set_api_key: Optional[str],
190
- config_str: Optional[str],
191
- query: Optional[str],
192
- continue_id: Optional[str] = None,
193
- continue_flag: Optional[str] = None,
194
- history_flag: bool = False,
195
- history_count: Optional[int] = None
196
- ) -> bool:
197
- """
198
- Handle all configuration-related commands.
199
-
200
- Args:
201
- ctx: Typer context
202
- reset_config: Whether to reset the configuration
203
- workspace: Workspace directory path
204
- show_config: Whether to show the configuration
205
- profile: Profile name
206
- role: Role name
207
- set_api_key: API key
208
- config_str: Configuration string in format 'key=value'
209
- query: Query string
210
- continue_id: Optional message ID to continue a specific conversation
211
- continue_flag: Optional string that can be empty (flag only) or contain a chat ID
212
- history_flag: Whether to show conversation history (--history flag)
213
- history_count: Number of history entries to display (value after --history)
214
-
215
- Returns:
216
- bool: True if the program should exit after these operations
217
- """
218
- # Handle each command and check if we should exit after it
219
- if handle_reset_config(reset_config, ctx, query):
220
- return True
221
-
222
- handle_workspace(workspace)
223
-
224
- if handle_show_config(show_config, ctx, query):
225
- return True
226
-
227
- if handle_profile(profile, ctx, query):
228
- return True
229
-
230
- if handle_role(role, ctx, query):
231
- return True
232
-
233
- if handle_set_api_key(set_api_key, ctx, query):
234
- return True
235
-
236
- if handle_set_config(config_str, ctx, query):
237
- return True
238
-
239
- if handle_history(history_flag, history_count, ctx, query):
240
- return True
241
-
242
- return False
@@ -1,119 +0,0 @@
1
- """
2
- History management functions for Janito CLI.
3
- """
4
- import sys
5
- import json
6
- import datetime
7
- from pathlib import Path
8
- from typing import Optional, List, Dict, Any
9
- import typer
10
- from rich.console import Console
11
- from rich.table import Table
12
-
13
- from janito.config import get_config
14
-
15
- console = Console()
16
-
17
- def handle_history(history_flag: bool, history_count: Optional[int], ctx: typer.Context, query: Optional[str]) -> bool:
18
- """
19
- Handle the --history parameter to display conversation history.
20
-
21
- Args:
22
- history_flag: Whether to show history (--history flag)
23
- history_count: Number of history entries to display (value after --history)
24
- ctx: Typer context
25
- query: Query string
26
-
27
- Returns:
28
- bool: True if the program should exit after this operation
29
- """
30
- # Check if --history was used
31
- if history_flag:
32
- try:
33
- # If --history is used with a count value passed from app.py, use that
34
- # If no count is specified, default to 20
35
- count = 20 if history_count is None else history_count
36
-
37
- # Get the workspace directory
38
- workspace_dir = Path(get_config().workspace_dir)
39
- janito_dir = workspace_dir / ".janito"
40
- messages_dir = janito_dir / "last_messages"
41
-
42
- if not messages_dir.exists() or not any(messages_dir.iterdir()):
43
- console.print("[bold yellow]⚠️ No conversation history found[/bold yellow]")
44
- return True # Always exit after displaying history
45
-
46
- # Find all message files and sort by timestamp (newest first)
47
- message_files = [f for f in messages_dir.iterdir() if f.is_file() and f.suffix == '.json']
48
- message_files.sort(key=lambda x: x.stem, reverse=True)
49
-
50
- # Limit to the requested number of entries
51
- message_files = message_files[:count]
52
-
53
- # Create a table for the history
54
- table = Table(title=f"Conversation History (Last {min(count, len(message_files))} Entries)")
55
- table.add_column("ID", style="cyan")
56
- table.add_column("Date", style="green")
57
- table.add_column("Time", style="green")
58
- table.add_column("First Query", style="yellow")
59
-
60
- # Add rows to the table
61
- for file in message_files:
62
- try:
63
- with open(file, "r", encoding="utf-8") as f:
64
- message_object = json.load(f)
65
-
66
- # Extract message ID and timestamp
67
- message_id = message_object.get("id", file.stem)
68
-
69
- # Parse timestamp
70
- timestamp_str = message_object.get("timestamp")
71
- if timestamp_str:
72
- timestamp = datetime.datetime.fromisoformat(timestamp_str)
73
- date_str = timestamp.strftime("%Y-%m-%d")
74
- time_str = timestamp.strftime("%H:%M:%S")
75
- else:
76
- # Fallback to file name which is a timestamp
77
- timestamp_str = file.stem
78
- date_str = timestamp_str[:8] # YYYYMMDD
79
- time_str = timestamp_str[8:] # HHMMSS
80
-
81
- # Format the date and time
82
- if len(date_str) == 8:
83
- date_str = f"{date_str[:4]}-{date_str[4:6]}-{date_str[6:8]}"
84
- if len(time_str) == 6:
85
- time_str = f"{time_str[:2]}:{time_str[2:4]}:{time_str[4:6]}"
86
-
87
- # Extract the first user message
88
- messages = message_object.get("messages", [])
89
- first_query = "N/A"
90
- for msg in messages:
91
- if msg.get("role") == "user":
92
- first_query = msg.get("content", "N/A")
93
- # Truncate long queries
94
- if len(first_query) > 60:
95
- first_query = first_query[:57] + "..."
96
- break
97
-
98
- table.add_row(message_id, date_str, time_str, first_query)
99
- except Exception as e:
100
- table.add_row(file.stem, "Error", "Error", f"Failed to parse: {str(e)}")
101
-
102
- console.print(table)
103
-
104
- # Display information about how to continue conversations
105
- console.print("\n[bold blue]💡 To continue a conversation:[/bold blue]")
106
- script_name = "janito"
107
- if sys.argv[0].endswith(('janito', 'janito.exe')):
108
- console.print(f" {script_name} --continue <ID> <request>")
109
- else:
110
- console.print(f" python -m janito --continue <ID> <request>")
111
-
112
- # If --history flag is used, always exit regardless of whether a query is provided
113
- return True
114
-
115
- except Exception as e:
116
- console.print(f"[bold red]Error displaying history:[/bold red] {str(e)}")
117
- return True # Exit on error
118
-
119
- return False
@@ -1,72 +0,0 @@
1
- """
2
- Profile and role management functions for Janito CLI.
3
- """
4
- import sys
5
- from typing import Optional
6
- import typer
7
- from rich.console import Console
8
-
9
- from janito.config import get_config
10
-
11
- console = Console()
12
-
13
- def handle_profile(profile: Optional[str], ctx: typer.Context, query: Optional[str]) -> bool:
14
- """
15
- Handle the --profile parameter.
16
-
17
- Args:
18
- profile: Profile name
19
- ctx: Typer context
20
- query: Query string
21
-
22
- Returns:
23
- bool: True if the program should exit after this operation
24
- """
25
- if profile is not None:
26
- try:
27
- # Apply profile without saving to config
28
- config = get_config()
29
- profile_data = config.get_available_profiles()[profile.lower()]
30
-
31
- # Set values directly without saving
32
- config._temperature = profile_data["temperature"]
33
- config._profile = profile.lower()
34
-
35
- console.print(f"[bold green]✅ Profile '{profile.lower()}' applied for this session only[/bold green]")
36
- console.print(f"[dim]📝 Description: {profile_data['description']}[/dim]")
37
-
38
- # Exit after applying profile if no other operation is requested
39
- return ctx.invoked_subcommand is None and not query
40
- except ValueError as e:
41
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
42
- sys.exit(1)
43
-
44
- return False
45
-
46
- def handle_role(role: Optional[str], ctx: typer.Context, query: Optional[str]) -> bool:
47
- """
48
- Handle the --role parameter.
49
-
50
- Args:
51
- role: Role name
52
- ctx: Typer context
53
- query: Query string
54
-
55
- Returns:
56
- bool: True if the program should exit after this operation
57
- """
58
- if role is not None:
59
- try:
60
- # Set role directly without saving to config
61
- config = get_config()
62
- config._role = role
63
-
64
- console.print(f"[bold green]✅ Role '{role}' applied for this session only[/bold green]")
65
-
66
- # Exit after applying role if no other operation is requested
67
- return ctx.invoked_subcommand is None and not query
68
- except Exception as e:
69
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
70
- sys.exit(1)
71
-
72
- return False
@@ -1,24 +0,0 @@
1
- """
2
- Parameter validation functions for Janito CLI.
3
- """
4
- import sys
5
- from rich.console import Console
6
-
7
- console = Console()
8
-
9
- def validate_parameters(temperature: float) -> None:
10
- """
11
- Validate temperature parameter.
12
-
13
- Args:
14
- temperature: Temperature value for model generation
15
- """
16
- try:
17
- if temperature < 0.0 or temperature > 1.0:
18
- raise ValueError("Temperature must be between 0.0 and 1.0")
19
-
20
- # We'll use this value directly in the agent initialization but we don't save it to config
21
- # Temperature display is hidden
22
- except ValueError as e:
23
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
24
- sys.exit(1)
@@ -1,31 +0,0 @@
1
- """
2
- Workspace management functions for Janito CLI.
3
- """
4
- import sys
5
- from typing import Optional
6
- from rich.console import Console
7
-
8
- from janito.config import get_config
9
-
10
- console = Console()
11
-
12
- def handle_workspace(workspace: Optional[str]) -> bool:
13
- """
14
- Handle the --workspace parameter.
15
-
16
- Args:
17
- workspace: Workspace directory path
18
-
19
- Returns:
20
- bool: True if the program should exit after this operation
21
- """
22
- if workspace:
23
- try:
24
- console.print(f"[bold]📂 Setting workspace directory to: {workspace}[/bold]")
25
- get_config().workspace_dir = workspace
26
- console.print(f"[bold green]✅ Workspace directory set to: {get_config().workspace_dir}[/bold green]")
27
- except ValueError as e:
28
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
29
- sys.exit(1)
30
-
31
- return False