omnimancer-cli 0.1.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.
- omnimancer/__init__.py +42 -0
- omnimancer/__main__.py +9 -0
- omnimancer/cli/__init__.py +8 -0
- omnimancer/cli/agent_manager.py +826 -0
- omnimancer/cli/agent_wizard.py +944 -0
- omnimancer/cli/approval_formatter.py +734 -0
- omnimancer/cli/approval_integration.py +734 -0
- omnimancer/cli/approval_prompt.py +1286 -0
- omnimancer/cli/batch_approval_display.py +617 -0
- omnimancer/cli/batch_approval_filters.py +729 -0
- omnimancer/cli/batch_operation_monitor.py +775 -0
- omnimancer/cli/commands/performance_cmd.py +624 -0
- omnimancer/cli/commands.py +757 -0
- omnimancer/cli/completion_handler.py +281 -0
- omnimancer/cli/config_setup_wizard.py +783 -0
- omnimancer/cli/dynamic_commands.py +371 -0
- omnimancer/cli/handlers/__init__.py +18 -0
- omnimancer/cli/handlers/agent_handler.py +865 -0
- omnimancer/cli/handlers/agent_persona_handler.py +1048 -0
- omnimancer/cli/handlers/custom_agent_handler.py +352 -0
- omnimancer/cli/handlers/permissions_handler.py +1609 -0
- omnimancer/cli/interface.py +6695 -0
- omnimancer/cli/performance_dashboard.py +612 -0
- omnimancer/core/__init__.py +34 -0
- omnimancer/core/agent/__init__.py +256 -0
- omnimancer/core/agent/agent_config.py +715 -0
- omnimancer/core/agent/agent_switcher.py +668 -0
- omnimancer/core/agent/approval_context.py +460 -0
- omnimancer/core/agent/approval_dialog.py +902 -0
- omnimancer/core/agent/approval_interface.py +628 -0
- omnimancer/core/agent/approval_manager.py +760 -0
- omnimancer/core/agent/cli_integration.py +470 -0
- omnimancer/core/agent/config.py +845 -0
- omnimancer/core/agent/custom_agent_integration.py +654 -0
- omnimancer/core/agent/diff_renderer.py +706 -0
- omnimancer/core/agent/file_content_display.py +503 -0
- omnimancer/core/agent/file_modification_workflow.py +658 -0
- omnimancer/core/agent/file_system_manager.py +1790 -0
- omnimancer/core/agent/input_handler.py +614 -0
- omnimancer/core/agent/metrics_collector.py +771 -0
- omnimancer/core/agent/optimization_engine.py +729 -0
- omnimancer/core/agent/performance_monitor.py +717 -0
- omnimancer/core/agent/persona.py +870 -0
- omnimancer/core/agent/persona_validator.py +672 -0
- omnimancer/core/agent/program_executor.py +748 -0
- omnimancer/core/agent/proposed_changes_integration.py +663 -0
- omnimancer/core/agent/read_before_write_errors.py +492 -0
- omnimancer/core/agent/read_before_write_ui.py +647 -0
- omnimancer/core/agent/rich_renderer.py +763 -0
- omnimancer/core/agent/status_config.py +238 -0
- omnimancer/core/agent/status_core.py +446 -0
- omnimancer/core/agent/status_integrated_engine.py +540 -0
- omnimancer/core/agent/status_manager.py +878 -0
- omnimancer/core/agent/status_ui_components.py +535 -0
- omnimancer/core/agent/template_applicator.py +548 -0
- omnimancer/core/agent/terminal_status_listener.py +394 -0
- omnimancer/core/agent/token_tracker.py +679 -0
- omnimancer/core/agent/types.py +60 -0
- omnimancer/core/agent/web_client.py +745 -0
- omnimancer/core/agent/workflow_orchestrator.py +826 -0
- omnimancer/core/agent_engine.py +1625 -0
- omnimancer/core/agent_mode_manager.py +706 -0
- omnimancer/core/agent_progress_ui.py +545 -0
- omnimancer/core/chat_manager.py +141 -0
- omnimancer/core/config_manager.py +2199 -0
- omnimancer/core/config_migration.py +772 -0
- omnimancer/core/config_provider.py +1974 -0
- omnimancer/core/config_security_validator.py +393 -0
- omnimancer/core/config_validator.py +768 -0
- omnimancer/core/conversation_manager.py +352 -0
- omnimancer/core/engine.py +787 -0
- omnimancer/core/enhanced_input.py +523 -0
- omnimancer/core/env_loader.py +83 -0
- omnimancer/core/fallback_manager.py +568 -0
- omnimancer/core/health_monitor.py +462 -0
- omnimancer/core/history_manager.py +462 -0
- omnimancer/core/mcp_integration_layer.py +878 -0
- omnimancer/core/models.py +1889 -0
- omnimancer/core/provider_capabilities.py +403 -0
- omnimancer/core/provider_initializer.py +450 -0
- omnimancer/core/provider_registry.py +432 -0
- omnimancer/core/security/__init__.py +16 -0
- omnimancer/core/security/approval_workflow.py +406 -0
- omnimancer/core/security/audit_logger.py +511 -0
- omnimancer/core/security/permission_controller.py +511 -0
- omnimancer/core/security/sandbox_manager.py +379 -0
- omnimancer/core/security/security_manager.py +530 -0
- omnimancer/core/setup_wizard.py +345 -0
- omnimancer/core/setup_wizard_core.py +449 -0
- omnimancer/core/setup_wizard_guide_generator.py +376 -0
- omnimancer/core/setup_wizard_provider_setup.py +454 -0
- omnimancer/core/setup_wizard_ui.py +317 -0
- omnimancer/core/setup_wizard_validation.py +371 -0
- omnimancer/core/signal_handler.py +174 -0
- omnimancer/mcp/__init__.py +11 -0
- omnimancer/mcp/client.py +725 -0
- omnimancer/mcp/manager.py +649 -0
- omnimancer/providers/__init__.py +24 -0
- omnimancer/providers/azure.py +608 -0
- omnimancer/providers/base.py +262 -0
- omnimancer/providers/bedrock.py +711 -0
- omnimancer/providers/claude.py +426 -0
- omnimancer/providers/claude_code.py +406 -0
- omnimancer/providers/cohere.py +412 -0
- omnimancer/providers/factory.py +988 -0
- omnimancer/providers/gemini.py +708 -0
- omnimancer/providers/mistral.py +554 -0
- omnimancer/providers/ollama.py +510 -0
- omnimancer/providers/openai.py +362 -0
- omnimancer/providers/openrouter.py +709 -0
- omnimancer/providers/perplexity.py +476 -0
- omnimancer/providers/vertex.py +617 -0
- omnimancer/providers/xai.py +484 -0
- omnimancer/ui/__init__.py +6 -0
- omnimancer/ui/cancellation_handler.py +235 -0
- omnimancer/ui/progress_indicator.py +318 -0
- omnimancer/utils/__init__.py +22 -0
- omnimancer/utils/error_handler.py +589 -0
- omnimancer/utils/errors.py +667 -0
- omnimancer/utils/retry.py +238 -0
- omnimancer_cli-0.1.0.dist-info/METADATA +413 -0
- omnimancer_cli-0.1.0.dist-info/RECORD +126 -0
- omnimancer_cli-0.1.0.dist-info/WHEEL +5 -0
- omnimancer_cli-0.1.0.dist-info/entry_points.txt +4 -0
- omnimancer_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- omnimancer_cli-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom Agent CLI Handler for Omnimancer.
|
|
3
|
+
|
|
4
|
+
This module provides the CustomAgentHandler class that processes custom agent
|
|
5
|
+
management commands including creation, listing, loading, and configuration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import List, Optional
|
|
11
|
+
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
from rich.panel import Panel
|
|
14
|
+
from rich.prompt import Confirm
|
|
15
|
+
|
|
16
|
+
from ..agent_manager import create_agent_manager
|
|
17
|
+
from ..commands import Command
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CustomAgentHandler:
|
|
23
|
+
"""Handles custom agent CLI commands."""
|
|
24
|
+
|
|
25
|
+
def __init__(self, console: Optional[Console] = None):
|
|
26
|
+
"""
|
|
27
|
+
Initialize the handler.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
console: Rich console for output
|
|
31
|
+
"""
|
|
32
|
+
self.console = console or Console()
|
|
33
|
+
self.agent_manager = create_agent_manager(self.console)
|
|
34
|
+
|
|
35
|
+
async def handle_custom_agent_command(self, command: Command) -> None:
|
|
36
|
+
"""
|
|
37
|
+
Handle /agent commands for custom agent management.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
command: Parsed command object
|
|
41
|
+
"""
|
|
42
|
+
try:
|
|
43
|
+
args = command.parameters.get("args", [])
|
|
44
|
+
|
|
45
|
+
if not args:
|
|
46
|
+
await self._show_help()
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
subcommand = args[0].lower()
|
|
50
|
+
remaining_args = args[1:]
|
|
51
|
+
|
|
52
|
+
# Route to appropriate handler
|
|
53
|
+
if subcommand == "list":
|
|
54
|
+
await self._handle_list_agents(remaining_args)
|
|
55
|
+
elif subcommand == "show":
|
|
56
|
+
await self._handle_show_agent(remaining_args)
|
|
57
|
+
elif subcommand == "create":
|
|
58
|
+
await self._handle_create_agent(remaining_args)
|
|
59
|
+
elif subcommand == "load":
|
|
60
|
+
await self._handle_load_agent(remaining_args)
|
|
61
|
+
elif subcommand == "delete":
|
|
62
|
+
await self._handle_delete_agent(remaining_args)
|
|
63
|
+
elif subcommand == "clone":
|
|
64
|
+
await self._handle_clone_agent(remaining_args)
|
|
65
|
+
elif subcommand == "search":
|
|
66
|
+
await self._handle_search_agents(remaining_args)
|
|
67
|
+
elif subcommand == "export":
|
|
68
|
+
await self._handle_export_agent(remaining_args)
|
|
69
|
+
elif subcommand == "import":
|
|
70
|
+
await self._handle_import_agent(remaining_args)
|
|
71
|
+
elif subcommand == "stats":
|
|
72
|
+
await self._handle_show_statistics(remaining_args)
|
|
73
|
+
elif subcommand == "active":
|
|
74
|
+
await self._handle_show_active(remaining_args)
|
|
75
|
+
else:
|
|
76
|
+
self.console.print(f"[red]Unknown subcommand: {subcommand}[/red]")
|
|
77
|
+
await self._show_help()
|
|
78
|
+
|
|
79
|
+
except Exception as e:
|
|
80
|
+
self.console.print(f"[red]Error handling agent command: {e}[/red]")
|
|
81
|
+
logger.error(f"Custom agent command error: {e}", exc_info=True)
|
|
82
|
+
|
|
83
|
+
async def _show_help(self):
|
|
84
|
+
"""Show help for custom agent commands."""
|
|
85
|
+
help_text = """
|
|
86
|
+
[bold cyan]Custom Agent Management Commands[/bold cyan]
|
|
87
|
+
|
|
88
|
+
[yellow]Basic Operations:[/yellow]
|
|
89
|
+
/agent list [--category <cat>] [--status <status>] [--details]
|
|
90
|
+
List all custom agents with optional filtering
|
|
91
|
+
|
|
92
|
+
/agent show <name|id>
|
|
93
|
+
Show detailed information about a specific agent
|
|
94
|
+
|
|
95
|
+
/agent create
|
|
96
|
+
Launch interactive wizard to create a new agent
|
|
97
|
+
|
|
98
|
+
/agent load <name|id>
|
|
99
|
+
Load and activate an agent for the current session
|
|
100
|
+
|
|
101
|
+
[yellow]Management:[/yellow]
|
|
102
|
+
/agent delete <name|id>
|
|
103
|
+
Delete an agent configuration
|
|
104
|
+
|
|
105
|
+
/agent clone <source> <new_name>
|
|
106
|
+
Clone an existing agent with a new name
|
|
107
|
+
|
|
108
|
+
/agent search <query>
|
|
109
|
+
Search agents by name, description, or capabilities
|
|
110
|
+
|
|
111
|
+
[yellow]Import/Export:[/yellow]
|
|
112
|
+
/agent export <name|id> [--path <file>]
|
|
113
|
+
Export agent configuration to file
|
|
114
|
+
|
|
115
|
+
/agent import <file> [--name <new_name>]
|
|
116
|
+
Import agent configuration from file
|
|
117
|
+
|
|
118
|
+
[yellow]Information:[/yellow]
|
|
119
|
+
/agent stats
|
|
120
|
+
Show repository and session statistics
|
|
121
|
+
|
|
122
|
+
/agent active
|
|
123
|
+
Show currently active agent
|
|
124
|
+
|
|
125
|
+
[yellow]Examples:[/yellow]
|
|
126
|
+
/agent list --category development --details
|
|
127
|
+
/agent show my-coding-assistant
|
|
128
|
+
/agent load my-coding-assistant
|
|
129
|
+
/agent clone my-coding-assistant my-new-assistant
|
|
130
|
+
/agent search "web development"
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
self.console.print(
|
|
134
|
+
Panel(help_text, title="🤖 Custom Agent Commands", expand=False)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
async def _handle_list_agents(self, args: List[str]):
|
|
138
|
+
"""Handle agent listing command."""
|
|
139
|
+
# Parse options
|
|
140
|
+
category = None
|
|
141
|
+
status = None
|
|
142
|
+
show_details = False
|
|
143
|
+
sort_by = "name"
|
|
144
|
+
|
|
145
|
+
i = 0
|
|
146
|
+
while i < len(args):
|
|
147
|
+
if args[i] == "--category" and i + 1 < len(args):
|
|
148
|
+
category = args[i + 1]
|
|
149
|
+
i += 2
|
|
150
|
+
elif args[i] == "--status" and i + 1 < len(args):
|
|
151
|
+
status = args[i + 1]
|
|
152
|
+
i += 2
|
|
153
|
+
elif args[i] == "--details":
|
|
154
|
+
show_details = True
|
|
155
|
+
i += 1
|
|
156
|
+
elif args[i] == "--sort" and i + 1 < len(args):
|
|
157
|
+
sort_by = args[i + 1]
|
|
158
|
+
i += 2
|
|
159
|
+
else:
|
|
160
|
+
i += 1
|
|
161
|
+
|
|
162
|
+
await self.agent_manager.list_agents(
|
|
163
|
+
category=category,
|
|
164
|
+
status=status,
|
|
165
|
+
show_details=show_details,
|
|
166
|
+
sort_by=sort_by,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
async def _handle_show_agent(self, args: List[str]):
|
|
170
|
+
"""Handle show agent command."""
|
|
171
|
+
if not args:
|
|
172
|
+
self.console.print("[red]Please specify an agent name or ID.[/red]")
|
|
173
|
+
self.console.print("Usage: /agent show <name|id>")
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
identifier = " ".join(args) # Handle names with spaces
|
|
177
|
+
await self.agent_manager.show_agent(identifier)
|
|
178
|
+
|
|
179
|
+
async def _handle_create_agent(self, args: List[str]):
|
|
180
|
+
"""Handle create agent command."""
|
|
181
|
+
# Check for quick creation options
|
|
182
|
+
interactive = True
|
|
183
|
+
|
|
184
|
+
if "--quick" in args:
|
|
185
|
+
interactive = False
|
|
186
|
+
self.console.print(
|
|
187
|
+
"[yellow]Quick creation not yet implemented. Using interactive mode.[/yellow]"
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
agent = await self.agent_manager.create_agent(interactive=interactive)
|
|
191
|
+
|
|
192
|
+
if agent:
|
|
193
|
+
self.console.print(
|
|
194
|
+
f"\\n[green]Agent '{agent.name}' created successfully![/green]"
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# Ask if user wants to load it immediately
|
|
198
|
+
if Confirm.ask("Load this agent now?", default=True):
|
|
199
|
+
await self.agent_manager.load_agent(agent.id, activate=True)
|
|
200
|
+
|
|
201
|
+
async def _handle_load_agent(self, args: List[str]):
|
|
202
|
+
"""Handle load agent command."""
|
|
203
|
+
if not args:
|
|
204
|
+
self.console.print("[red]Please specify an agent name or ID.[/red]")
|
|
205
|
+
self.console.print("Usage: /agent load <name|id>")
|
|
206
|
+
return
|
|
207
|
+
|
|
208
|
+
identifier = " ".join(args)
|
|
209
|
+
await self.agent_manager.load_agent(identifier, activate=True)
|
|
210
|
+
|
|
211
|
+
async def _handle_delete_agent(self, args: List[str]):
|
|
212
|
+
"""Handle delete agent command."""
|
|
213
|
+
if not args:
|
|
214
|
+
self.console.print("[red]Please specify an agent name or ID.[/red]")
|
|
215
|
+
self.console.print("Usage: /agent delete <name|id>")
|
|
216
|
+
return
|
|
217
|
+
|
|
218
|
+
identifier = " ".join(args)
|
|
219
|
+
|
|
220
|
+
# Check for --force flag
|
|
221
|
+
force = "--force" in args
|
|
222
|
+
if force:
|
|
223
|
+
args = [arg for arg in args if arg != "--force"]
|
|
224
|
+
identifier = " ".join(args)
|
|
225
|
+
|
|
226
|
+
await self.agent_manager.delete_agent(identifier, confirm=not force)
|
|
227
|
+
|
|
228
|
+
async def _handle_clone_agent(self, args: List[str]):
|
|
229
|
+
"""Handle clone agent command."""
|
|
230
|
+
if len(args) < 2:
|
|
231
|
+
self.console.print("[red]Please specify source agent and new name.[/red]")
|
|
232
|
+
self.console.print("Usage: /agent clone <source> <new_name>")
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
source_identifier = args[0]
|
|
236
|
+
new_name = " ".join(args[1:]) # Handle names with spaces
|
|
237
|
+
|
|
238
|
+
await self.agent_manager.clone_agent(source_identifier, new_name)
|
|
239
|
+
|
|
240
|
+
async def _handle_search_agents(self, args: List[str]):
|
|
241
|
+
"""Handle search agents command."""
|
|
242
|
+
if not args:
|
|
243
|
+
self.console.print("[red]Please specify a search query.[/red]")
|
|
244
|
+
self.console.print("Usage: /agent search <query>")
|
|
245
|
+
return
|
|
246
|
+
|
|
247
|
+
query = " ".join(args)
|
|
248
|
+
|
|
249
|
+
# Check for field restrictions
|
|
250
|
+
fields = None
|
|
251
|
+
if "--fields" in args:
|
|
252
|
+
field_index = args.index("--fields")
|
|
253
|
+
if field_index + 1 < len(args):
|
|
254
|
+
fields = args[field_index + 1].split(",")
|
|
255
|
+
# Remove --fields and field list from query
|
|
256
|
+
args = args[:field_index] + args[field_index + 2 :]
|
|
257
|
+
query = " ".join(args)
|
|
258
|
+
|
|
259
|
+
await self.agent_manager.search_agents(query, fields)
|
|
260
|
+
|
|
261
|
+
async def _handle_export_agent(self, args: List[str]):
|
|
262
|
+
"""Handle export agent command."""
|
|
263
|
+
if not args:
|
|
264
|
+
self.console.print("[red]Please specify an agent name or ID.[/red]")
|
|
265
|
+
self.console.print("Usage: /agent export <name|id> [--path <file>]")
|
|
266
|
+
return
|
|
267
|
+
|
|
268
|
+
# Parse arguments
|
|
269
|
+
export_path = None
|
|
270
|
+
identifier_args = []
|
|
271
|
+
|
|
272
|
+
i = 0
|
|
273
|
+
while i < len(args):
|
|
274
|
+
if args[i] == "--path" and i + 1 < len(args):
|
|
275
|
+
export_path = Path(args[i + 1])
|
|
276
|
+
i += 2
|
|
277
|
+
else:
|
|
278
|
+
identifier_args.append(args[i])
|
|
279
|
+
i += 1
|
|
280
|
+
|
|
281
|
+
if not identifier_args:
|
|
282
|
+
self.console.print("[red]Please specify an agent name or ID.[/red]")
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
identifier = " ".join(identifier_args)
|
|
286
|
+
await self.agent_manager.export_agent(identifier, export_path)
|
|
287
|
+
|
|
288
|
+
async def _handle_import_agent(self, args: List[str]):
|
|
289
|
+
"""Handle import agent command."""
|
|
290
|
+
if not args:
|
|
291
|
+
self.console.print("[red]Please specify import file path.[/red]")
|
|
292
|
+
self.console.print("Usage: /agent import <file> [--name <new_name>]")
|
|
293
|
+
return
|
|
294
|
+
|
|
295
|
+
# Parse arguments
|
|
296
|
+
new_name = None
|
|
297
|
+
import_file = None
|
|
298
|
+
|
|
299
|
+
i = 0
|
|
300
|
+
while i < len(args):
|
|
301
|
+
if args[i] == "--name" and i + 1 < len(args):
|
|
302
|
+
new_name = args[i + 1]
|
|
303
|
+
i += 2
|
|
304
|
+
else:
|
|
305
|
+
if not import_file:
|
|
306
|
+
import_file = args[i]
|
|
307
|
+
i += 1
|
|
308
|
+
|
|
309
|
+
if not import_file:
|
|
310
|
+
self.console.print("[red]Please specify import file path.[/red]")
|
|
311
|
+
return
|
|
312
|
+
|
|
313
|
+
import_path = Path(import_file)
|
|
314
|
+
agent = await self.agent_manager.import_agent(import_path, new_name)
|
|
315
|
+
|
|
316
|
+
if agent:
|
|
317
|
+
# Ask if user wants to load it immediately
|
|
318
|
+
if Confirm.ask("Load this agent now?", default=False):
|
|
319
|
+
await self.agent_manager.load_agent(agent.id, activate=True)
|
|
320
|
+
|
|
321
|
+
async def _handle_show_statistics(self, args: List[str]):
|
|
322
|
+
"""Handle show statistics command."""
|
|
323
|
+
self.agent_manager.show_statistics()
|
|
324
|
+
|
|
325
|
+
async def _handle_show_active(self, args: List[str]):
|
|
326
|
+
"""Handle show active agent command."""
|
|
327
|
+
active_agent = self.agent_manager.get_active_agent()
|
|
328
|
+
|
|
329
|
+
if not active_agent:
|
|
330
|
+
self.console.print("[yellow]No agent is currently active.[/yellow]")
|
|
331
|
+
return
|
|
332
|
+
|
|
333
|
+
self.console.print(f"[green]Active Agent:[/green]")
|
|
334
|
+
await self.agent_manager.show_agent(active_agent.id)
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
# Utility functions for integration
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def create_custom_agent_handler(
|
|
341
|
+
console: Optional[Console] = None,
|
|
342
|
+
) -> CustomAgentHandler:
|
|
343
|
+
"""Create and initialize a custom agent handler."""
|
|
344
|
+
return CustomAgentHandler(console=console)
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
async def handle_agent_command(
|
|
348
|
+
command: Command, console: Optional[Console] = None
|
|
349
|
+
) -> None:
|
|
350
|
+
"""Handle agent command using the custom agent handler."""
|
|
351
|
+
handler = create_custom_agent_handler(console)
|
|
352
|
+
await handler.handle_custom_agent_command(command)
|