janito 0.13.0__py3-none-any.whl → 0.15.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 (50) hide show
  1. janito/__init__.py +1 -1
  2. janito/cli/agent/__init__.py +7 -0
  3. janito/cli/agent/conversation.py +149 -0
  4. janito/cli/agent/initialization.py +168 -0
  5. janito/cli/agent/query.py +112 -0
  6. janito/cli/agent.py +7 -395
  7. janito/cli/app.py +103 -19
  8. janito/cli/commands/__init__.py +12 -0
  9. janito/cli/commands/config.py +30 -0
  10. janito/cli/commands/history.py +119 -0
  11. janito/cli/commands/profile.py +93 -0
  12. janito/cli/commands/validation.py +24 -0
  13. janito/cli/commands/workspace.py +31 -0
  14. janito/cli/commands.py +9 -326
  15. janito/config/README.md +104 -0
  16. janito/config/__init__.py +16 -0
  17. janito/config/cli/__init__.py +28 -0
  18. janito/config/cli/commands.py +397 -0
  19. janito/config/cli/validators.py +77 -0
  20. janito/config/core/__init__.py +23 -0
  21. janito/config/core/file_operations.py +90 -0
  22. janito/config/core/properties.py +316 -0
  23. janito/config/core/singleton.py +282 -0
  24. janito/config/profiles/__init__.py +8 -0
  25. janito/config/profiles/definitions.py +38 -0
  26. janito/config/profiles/manager.py +80 -0
  27. janito/data/instructions_template.txt +12 -6
  28. janito/tools/__init__.py +8 -2
  29. janito/tools/bash/bash.py +80 -7
  30. janito/tools/bash/unix_persistent_bash.py +32 -1
  31. janito/tools/bash/win_persistent_bash.py +34 -1
  32. janito/tools/fetch_webpage/__init__.py +22 -33
  33. janito/tools/fetch_webpage/core.py +182 -155
  34. janito/tools/move_file.py +1 -1
  35. janito/tools/search_text.py +225 -239
  36. janito/tools/str_replace_editor/handlers/view.py +14 -8
  37. janito/tools/think.py +37 -0
  38. janito/tools/usage_tracker.py +1 -0
  39. {janito-0.13.0.dist-info → janito-0.15.0.dist-info}/METADATA +204 -23
  40. janito-0.15.0.dist-info/RECORD +64 -0
  41. janito/config.py +0 -358
  42. janito/test_file.py +0 -4
  43. janito/tools/fetch_webpage/chunking.py +0 -76
  44. janito/tools/fetch_webpage/extractors.py +0 -276
  45. janito/tools/fetch_webpage/news.py +0 -137
  46. janito/tools/fetch_webpage/utils.py +0 -108
  47. janito-0.13.0.dist-info/RECORD +0 -47
  48. {janito-0.13.0.dist-info → janito-0.15.0.dist-info}/WHEEL +0 -0
  49. {janito-0.13.0.dist-info → janito-0.15.0.dist-info}/entry_points.txt +0 -0
  50. {janito-0.13.0.dist-info → janito-0.15.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,119 @@
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
@@ -0,0 +1,93 @@
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 Config
10
+
11
+ console = Console()
12
+
13
+ def handle_profile(profile: Optional[str], ctx: typer.Context, query: Optional[str], config_type: str = "session") -> bool:
14
+ """
15
+ Handle the --profile parameter.
16
+
17
+ Args:
18
+ profile: Profile name
19
+ ctx: Typer context
20
+ query: Query string
21
+ config_type: Type of configuration to update ("session", "local", or "global")
22
+
23
+ Returns:
24
+ bool: True if the program should exit after this operation
25
+ """
26
+ if profile is not None:
27
+ try:
28
+ # Apply profile
29
+ config = Config()
30
+ profile_data = config.get_available_profiles()[profile.lower()]
31
+
32
+ if config_type == "session":
33
+ # Set values directly without saving
34
+ config._temperature = profile_data["temperature"]
35
+ config._profile = profile.lower()
36
+ console.print(f"[bold green]✅ Profile '{profile.lower()}' applied for this session only[/bold green]")
37
+ elif config_type in ["local", "global"]:
38
+ # Set profile in the specified configuration
39
+ config.set_profile(profile.lower(), config_type)
40
+ console.print(f"[bold green]✅ Profile '{profile.lower()}' set in {config_type} configuration[/bold green]")
41
+ else:
42
+ console.print(f"[bold red]Error:[/bold red] Invalid config_type: {config_type}")
43
+ return ctx.invoked_subcommand is None and not query
44
+
45
+ console.print(f"[dim]📝 Description: {profile_data['description']}[/dim]")
46
+
47
+ # Exit after applying profile if no other operation is requested
48
+ return ctx.invoked_subcommand is None and not query
49
+ except ValueError as e:
50
+ console.print(f"[bold red]Error:[/bold red] {str(e)}")
51
+ sys.exit(1)
52
+
53
+ return False
54
+
55
+ def handle_role(role: Optional[str], ctx: typer.Context, query: Optional[str], config_type: str = "session") -> bool:
56
+ """
57
+ Handle the --role parameter.
58
+
59
+ Args:
60
+ role: Role name
61
+ ctx: Typer context
62
+ query: Query string
63
+ config_type: Type of configuration to update ("session", "local", or "global")
64
+
65
+ Returns:
66
+ bool: True if the program should exit after this operation
67
+ """
68
+ if role is not None:
69
+ try:
70
+ config = Config()
71
+
72
+ if config_type == "session":
73
+ # Set role directly without saving
74
+ config._role = role
75
+ console.print(f"[bold green]✅ Role '{role}' applied for this session only[/bold green]")
76
+ elif config_type in ["local", "global"]:
77
+ # Set role in the specified configuration
78
+ if config_type == "local":
79
+ config.role = role, "local"
80
+ else:
81
+ config.role = role, "global"
82
+ console.print(f"[bold green]✅ Role '{role}' set in {config_type} configuration[/bold green]")
83
+ else:
84
+ console.print(f"[bold red]Error:[/bold red] Invalid config_type: {config_type}")
85
+ return ctx.invoked_subcommand is None and not query
86
+
87
+ # Exit after applying role if no other operation is requested
88
+ return ctx.invoked_subcommand is None and not query
89
+ except Exception as e:
90
+ console.print(f"[bold red]Error:[/bold red] {str(e)}")
91
+ sys.exit(1)
92
+
93
+ return False
@@ -0,0 +1,24 @@
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)
@@ -0,0 +1,31 @@
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 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
+ Config().workspace_dir = workspace
26
+ console.print(f"[bold green]✅ Workspace directory set to: {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
janito/cli/commands.py CHANGED
@@ -1,329 +1,12 @@
1
1
  """
2
2
  Command handling logic for Janito CLI.
3
+ This module serves as a compatibility layer for the reorganized commands module.
3
4
  """
4
- import sys
5
- import os
6
- from typing import Optional, Tuple, Any
7
- from pathlib import Path
8
- import typer
9
- from rich.console import Console
10
-
11
- from janito.config import get_config, Config
12
-
13
- console = Console()
14
-
15
- def validate_parameters(temperature: float) -> None:
16
- """
17
- Validate temperature parameter.
18
-
19
- Args:
20
- temperature: Temperature value for model generation
21
- """
22
- try:
23
- if temperature < 0.0 or temperature > 1.0:
24
- raise ValueError("Temperature must be between 0.0 and 1.0")
25
-
26
- # We'll use this value directly in the agent initialization but we don't save it to config
27
- # Temperature display is hidden
28
- except ValueError as e:
29
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
30
- sys.exit(1)
31
-
32
- def handle_reset_config(reset_config: bool, ctx: typer.Context, query: Optional[str]) -> bool:
33
- """
34
- Handle the --reset-config parameter.
35
-
36
- Args:
37
- reset_config: Whether to reset the configuration
38
- ctx: Typer context
39
- query: Query string
40
-
41
- Returns:
42
- bool: True if the program should exit after this operation
43
- """
44
- if reset_config:
45
- try:
46
- config_path = Path(get_config().workspace_dir) / ".janito" / "config.json"
47
- if get_config().reset_config():
48
- console.print(f"[bold green]✅ Configuration file removed: {config_path}[/bold green]")
49
- else:
50
- console.print(f"[bold yellow]⚠️ Configuration file does not exist: {config_path}[/bold yellow]")
51
- except Exception as e:
52
- console.print(f"[bold red]Error removing configuration file:[/bold red] {str(e)}")
53
-
54
- # Exit after resetting config if no other operation is requested
55
- return ctx.invoked_subcommand is None and not query
56
-
57
- return False
58
-
59
- def handle_workspace(workspace: Optional[str]) -> bool:
60
- """
61
- Handle the --workspace parameter.
62
-
63
- Args:
64
- workspace: Workspace directory path
65
-
66
- Returns:
67
- bool: True if the program should exit after this operation
68
- """
69
- if workspace:
70
- try:
71
- console.print(f"[bold]📂 Setting workspace directory to: {workspace}[/bold]")
72
- get_config().workspace_dir = workspace
73
- console.print(f"[bold green]✅ Workspace directory set to: {get_config().workspace_dir}[/bold green]")
74
- except ValueError as e:
75
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
76
- sys.exit(1)
77
-
78
- return False
79
-
80
- def handle_show_config(show_config: bool, ctx: typer.Context, query: Optional[str]) -> bool:
81
- """
82
- Handle the --show-config parameter.
83
-
84
- Args:
85
- show_config: Whether to show the configuration
86
- ctx: Typer context
87
- query: Query string
88
-
89
- Returns:
90
- bool: True if the program should exit after this operation
91
- """
92
- if show_config:
93
- config = get_config()
94
- console.print("[bold blue]⚙️ Current Configuration:[/bold blue]")
95
- console.print(f"[bold]📁 Local Configuration File:[/bold] .janito/config.json")
96
- console.print(f"[bold]🏠 Global Configuration File:[/bold] {Path.home() / '.janito' / 'config.json'}")
97
-
98
- # Show API key status
99
- api_key_global = Config.get_api_key()
100
- api_key_env = os.environ.get("ANTHROPIC_API_KEY")
101
- if api_key_global:
102
- console.print(f"[bold]🔑 API Key:[/bold] [green]Set in global config[/green]")
103
- elif api_key_env:
104
- console.print(f"[bold]🔑 API Key:[/bold] [yellow]Set in environment variable[/yellow]")
105
- else:
106
- console.print(f"[bold]🔑 API Key:[/bold] [red]Not set[/red]")
107
-
108
- console.print(f"[bold]🔊 Verbose Mode:[/bold] {'Enabled' if config.verbose else 'Disabled'}")
109
- console.print(f"[bold]❓ Ask Mode:[/bold] {'Enabled' if config.ask_mode else 'Disabled'}")
110
-
111
- console.print(f"[bold]👤 Role:[/bold] {config.role}")
112
-
113
- # Show profile information if one is set
114
- if config.profile:
115
- profile_data = config.get_available_profiles()[config.profile]
116
- console.print(f"[bold]📋 Active Profile:[/bold] {config.profile} - {profile_data['description']}")
117
-
118
- # Show available profiles
119
- profiles = config.get_available_profiles()
120
- if profiles:
121
- console.print("\n[bold blue]📋 Available Parameter Profiles:[/bold blue]")
122
- for name, data in profiles.items():
123
- console.print(f"[bold]🔹 {name}[/bold] - {data['description']}")
124
-
125
- # Exit if this was the only operation requested
126
- return ctx.invoked_subcommand is None and not query
127
-
128
- return False
129
-
130
- def handle_profile(profile: Optional[str], ctx: typer.Context, query: Optional[str]) -> bool:
131
- """
132
- Handle the --profile parameter.
133
-
134
- Args:
135
- profile: Profile name
136
- ctx: Typer context
137
- query: Query string
138
-
139
- Returns:
140
- bool: True if the program should exit after this operation
141
- """
142
- if profile is not None:
143
- try:
144
- # Apply profile without saving to config
145
- config = get_config()
146
- profile_data = config.get_available_profiles()[profile.lower()]
147
-
148
- # Set values directly without saving
149
- config._temperature = profile_data["temperature"]
150
- config._profile = profile.lower()
151
-
152
- console.print(f"[bold green]✅ Profile '{profile.lower()}' applied for this session only[/bold green]")
153
- console.print(f"[dim]📝 Description: {profile_data['description']}[/dim]")
154
-
155
- # Exit after applying profile if no other operation is requested
156
- return ctx.invoked_subcommand is None and not query
157
- except ValueError as e:
158
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
159
- sys.exit(1)
160
-
161
- return False
162
-
163
- def handle_role(role: Optional[str], ctx: typer.Context, query: Optional[str]) -> bool:
164
- """
165
- Handle the --role parameter.
166
-
167
- Args:
168
- role: Role name
169
- ctx: Typer context
170
- query: Query string
171
-
172
- Returns:
173
- bool: True if the program should exit after this operation
174
- """
175
- if role is not None:
176
- try:
177
- # Set role directly without saving to config
178
- config = get_config()
179
- config._role = role
180
-
181
- console.print(f"[bold green]✅ Role '{role}' applied for this session only[/bold green]")
182
-
183
- # Exit after applying role if no other operation is requested
184
- return ctx.invoked_subcommand is None and not query
185
- except Exception as e:
186
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
187
- sys.exit(1)
188
-
189
- return False
190
-
191
- def handle_set_api_key(set_api_key: Optional[str], ctx: typer.Context, query: Optional[str]) -> bool:
192
- """
193
- Handle the --set-api-key parameter.
194
-
195
- Args:
196
- set_api_key: API key
197
- ctx: Typer context
198
- query: Query string
199
-
200
- Returns:
201
- bool: True if the program should exit after this operation
202
- """
203
- if set_api_key is not None:
204
- try:
205
- Config.set_api_key(set_api_key)
206
- console.print(f"[bold green]✅ API key saved to global configuration[/bold green]")
207
- console.print(f"[dim]📁 Location: {Path.home() / '.janito' / 'config.json'}[/dim]")
208
-
209
- # Exit after setting API key if no other operation is requested
210
- return ctx.invoked_subcommand is None and not query
211
- except Exception as e:
212
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
213
- sys.exit(1)
214
-
215
- return False
216
-
217
- def handle_set_config(config_str: Optional[str], ctx: typer.Context, query: Optional[str]) -> bool:
218
- """
219
- Handle the --set-config parameter.
220
-
221
- Args:
222
- config_str: Configuration string in format 'key=value'
223
- ctx: Typer context
224
- query: Query string
225
-
226
- Returns:
227
- bool: True if the program should exit after this operation
228
- """
229
- if config_str is not None:
230
- try:
231
- # Parse the config string
232
- config_parts = config_str.split("=", 1)
233
- if len(config_parts) != 2:
234
- console.print(f"[bold red]Error:[/bold red] Invalid configuration format. Use 'key=value' format.")
235
- return ctx.invoked_subcommand is None and not query
236
-
237
- key = config_parts[0].strip()
238
- value = config_parts[1].strip()
239
-
240
- # Remove quotes if present
241
- if (value.startswith("'") and value.endswith("'")) or \
242
- (value.startswith('"') and value.endswith('"')):
243
- value = value[1:-1]
244
-
245
- if key == "profile":
246
- try:
247
- get_config().set_profile(value)
248
- profile_data = get_config().get_available_profiles()[value.lower()]
249
- console.print(f"[bold green]✅ Profile set to '{value.lower()}'[/bold green]")
250
- console.print(f"[dim]📝 Description: {profile_data['description']}[/dim]")
251
- except ValueError as e:
252
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
253
- elif key == "temperature":
254
- try:
255
- temp_value = float(value)
256
- if temp_value < 0.0 or temp_value > 1.0:
257
- console.print("[bold red]Error:[/bold red] Temperature must be between 0.0 and 1.0")
258
- return ctx.invoked_subcommand is None and not query
259
-
260
- get_config().temperature = temp_value
261
- console.print(f"[bold green]✅ Temperature set to {temp_value} and saved to configuration[/bold green]")
262
- except ValueError:
263
- console.print(f"[bold red]Error:[/bold red] Invalid temperature value: {value}. Must be a float between 0.0 and 1.0.")
264
- # top_k and top_p are now only accessible through profiles
265
- elif key == "role":
266
- get_config().role = value
267
- console.print(f"[bold green]✅ Role set to '{value}' and saved to configuration[/bold green]")
268
- else:
269
- console.print(f"[bold yellow]Warning:[/bold yellow] Unsupported configuration key: {key}")
270
-
271
- # Exit after applying config changes if no other operation is requested
272
- return ctx.invoked_subcommand is None and not query
273
- except Exception as e:
274
- console.print(f"[bold red]Error:[/bold red] {str(e)}")
275
-
276
- return False
277
-
278
- def handle_config_commands(
279
- ctx: typer.Context,
280
- reset_config: bool,
281
- workspace: Optional[str],
282
- show_config: bool,
283
- profile: Optional[str],
284
- role: Optional[str],
285
- set_api_key: Optional[str],
286
- config_str: Optional[str],
287
- query: Optional[str],
288
- continue_conversation: Optional[str] = None
289
- ) -> bool:
290
- """
291
- Handle all configuration-related commands.
292
-
293
- Args:
294
- ctx: Typer context
295
- reset_config: Whether to reset the configuration
296
- workspace: Workspace directory path
297
- show_config: Whether to show the configuration
298
- profile: Profile name
299
- role: Role name
300
- set_api_key: API key
301
- config_str: Configuration string in format 'key=value'
302
- query: Query string
303
- continue_conversation: Optional message ID to continue a specific conversation
304
-
305
- Returns:
306
- bool: True if the program should exit after these operations
307
- """
308
- # Handle each command and check if we should exit after it
309
- if handle_reset_config(reset_config, ctx, query):
310
- return True
311
-
312
- handle_workspace(workspace)
313
-
314
- if handle_show_config(show_config, ctx, query):
315
- return True
316
-
317
- if handle_profile(profile, ctx, query):
318
- return True
319
-
320
- if handle_role(role, ctx, query):
321
- return True
322
-
323
- if handle_set_api_key(set_api_key, ctx, query):
324
- return True
325
-
326
- if handle_set_config(config_str, ctx, query):
327
- return True
328
-
329
- return False
5
+ # Re-export the functions from the new module structure
6
+ from janito.cli.commands import handle_config_commands, validate_parameters, handle_history
7
+
8
+ __all__ = [
9
+ "handle_config_commands",
10
+ "validate_parameters",
11
+ "handle_history",
12
+ ]