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.
Files changed (126) hide show
  1. omnimancer/__init__.py +42 -0
  2. omnimancer/__main__.py +9 -0
  3. omnimancer/cli/__init__.py +8 -0
  4. omnimancer/cli/agent_manager.py +826 -0
  5. omnimancer/cli/agent_wizard.py +944 -0
  6. omnimancer/cli/approval_formatter.py +734 -0
  7. omnimancer/cli/approval_integration.py +734 -0
  8. omnimancer/cli/approval_prompt.py +1286 -0
  9. omnimancer/cli/batch_approval_display.py +617 -0
  10. omnimancer/cli/batch_approval_filters.py +729 -0
  11. omnimancer/cli/batch_operation_monitor.py +775 -0
  12. omnimancer/cli/commands/performance_cmd.py +624 -0
  13. omnimancer/cli/commands.py +757 -0
  14. omnimancer/cli/completion_handler.py +281 -0
  15. omnimancer/cli/config_setup_wizard.py +783 -0
  16. omnimancer/cli/dynamic_commands.py +371 -0
  17. omnimancer/cli/handlers/__init__.py +18 -0
  18. omnimancer/cli/handlers/agent_handler.py +865 -0
  19. omnimancer/cli/handlers/agent_persona_handler.py +1048 -0
  20. omnimancer/cli/handlers/custom_agent_handler.py +352 -0
  21. omnimancer/cli/handlers/permissions_handler.py +1609 -0
  22. omnimancer/cli/interface.py +6695 -0
  23. omnimancer/cli/performance_dashboard.py +612 -0
  24. omnimancer/core/__init__.py +34 -0
  25. omnimancer/core/agent/__init__.py +256 -0
  26. omnimancer/core/agent/agent_config.py +715 -0
  27. omnimancer/core/agent/agent_switcher.py +668 -0
  28. omnimancer/core/agent/approval_context.py +460 -0
  29. omnimancer/core/agent/approval_dialog.py +902 -0
  30. omnimancer/core/agent/approval_interface.py +628 -0
  31. omnimancer/core/agent/approval_manager.py +760 -0
  32. omnimancer/core/agent/cli_integration.py +470 -0
  33. omnimancer/core/agent/config.py +845 -0
  34. omnimancer/core/agent/custom_agent_integration.py +654 -0
  35. omnimancer/core/agent/diff_renderer.py +706 -0
  36. omnimancer/core/agent/file_content_display.py +503 -0
  37. omnimancer/core/agent/file_modification_workflow.py +658 -0
  38. omnimancer/core/agent/file_system_manager.py +1790 -0
  39. omnimancer/core/agent/input_handler.py +614 -0
  40. omnimancer/core/agent/metrics_collector.py +771 -0
  41. omnimancer/core/agent/optimization_engine.py +729 -0
  42. omnimancer/core/agent/performance_monitor.py +717 -0
  43. omnimancer/core/agent/persona.py +870 -0
  44. omnimancer/core/agent/persona_validator.py +672 -0
  45. omnimancer/core/agent/program_executor.py +748 -0
  46. omnimancer/core/agent/proposed_changes_integration.py +663 -0
  47. omnimancer/core/agent/read_before_write_errors.py +492 -0
  48. omnimancer/core/agent/read_before_write_ui.py +647 -0
  49. omnimancer/core/agent/rich_renderer.py +763 -0
  50. omnimancer/core/agent/status_config.py +238 -0
  51. omnimancer/core/agent/status_core.py +446 -0
  52. omnimancer/core/agent/status_integrated_engine.py +540 -0
  53. omnimancer/core/agent/status_manager.py +878 -0
  54. omnimancer/core/agent/status_ui_components.py +535 -0
  55. omnimancer/core/agent/template_applicator.py +548 -0
  56. omnimancer/core/agent/terminal_status_listener.py +394 -0
  57. omnimancer/core/agent/token_tracker.py +679 -0
  58. omnimancer/core/agent/types.py +60 -0
  59. omnimancer/core/agent/web_client.py +745 -0
  60. omnimancer/core/agent/workflow_orchestrator.py +826 -0
  61. omnimancer/core/agent_engine.py +1625 -0
  62. omnimancer/core/agent_mode_manager.py +706 -0
  63. omnimancer/core/agent_progress_ui.py +545 -0
  64. omnimancer/core/chat_manager.py +141 -0
  65. omnimancer/core/config_manager.py +2199 -0
  66. omnimancer/core/config_migration.py +772 -0
  67. omnimancer/core/config_provider.py +1974 -0
  68. omnimancer/core/config_security_validator.py +393 -0
  69. omnimancer/core/config_validator.py +768 -0
  70. omnimancer/core/conversation_manager.py +352 -0
  71. omnimancer/core/engine.py +787 -0
  72. omnimancer/core/enhanced_input.py +523 -0
  73. omnimancer/core/env_loader.py +83 -0
  74. omnimancer/core/fallback_manager.py +568 -0
  75. omnimancer/core/health_monitor.py +462 -0
  76. omnimancer/core/history_manager.py +462 -0
  77. omnimancer/core/mcp_integration_layer.py +878 -0
  78. omnimancer/core/models.py +1889 -0
  79. omnimancer/core/provider_capabilities.py +403 -0
  80. omnimancer/core/provider_initializer.py +450 -0
  81. omnimancer/core/provider_registry.py +432 -0
  82. omnimancer/core/security/__init__.py +16 -0
  83. omnimancer/core/security/approval_workflow.py +406 -0
  84. omnimancer/core/security/audit_logger.py +511 -0
  85. omnimancer/core/security/permission_controller.py +511 -0
  86. omnimancer/core/security/sandbox_manager.py +379 -0
  87. omnimancer/core/security/security_manager.py +530 -0
  88. omnimancer/core/setup_wizard.py +345 -0
  89. omnimancer/core/setup_wizard_core.py +449 -0
  90. omnimancer/core/setup_wizard_guide_generator.py +376 -0
  91. omnimancer/core/setup_wizard_provider_setup.py +454 -0
  92. omnimancer/core/setup_wizard_ui.py +317 -0
  93. omnimancer/core/setup_wizard_validation.py +371 -0
  94. omnimancer/core/signal_handler.py +174 -0
  95. omnimancer/mcp/__init__.py +11 -0
  96. omnimancer/mcp/client.py +725 -0
  97. omnimancer/mcp/manager.py +649 -0
  98. omnimancer/providers/__init__.py +24 -0
  99. omnimancer/providers/azure.py +608 -0
  100. omnimancer/providers/base.py +262 -0
  101. omnimancer/providers/bedrock.py +711 -0
  102. omnimancer/providers/claude.py +426 -0
  103. omnimancer/providers/claude_code.py +406 -0
  104. omnimancer/providers/cohere.py +412 -0
  105. omnimancer/providers/factory.py +988 -0
  106. omnimancer/providers/gemini.py +708 -0
  107. omnimancer/providers/mistral.py +554 -0
  108. omnimancer/providers/ollama.py +510 -0
  109. omnimancer/providers/openai.py +362 -0
  110. omnimancer/providers/openrouter.py +709 -0
  111. omnimancer/providers/perplexity.py +476 -0
  112. omnimancer/providers/vertex.py +617 -0
  113. omnimancer/providers/xai.py +484 -0
  114. omnimancer/ui/__init__.py +6 -0
  115. omnimancer/ui/cancellation_handler.py +235 -0
  116. omnimancer/ui/progress_indicator.py +318 -0
  117. omnimancer/utils/__init__.py +22 -0
  118. omnimancer/utils/error_handler.py +589 -0
  119. omnimancer/utils/errors.py +667 -0
  120. omnimancer/utils/retry.py +238 -0
  121. omnimancer_cli-0.1.0.dist-info/METADATA +413 -0
  122. omnimancer_cli-0.1.0.dist-info/RECORD +126 -0
  123. omnimancer_cli-0.1.0.dist-info/WHEEL +5 -0
  124. omnimancer_cli-0.1.0.dist-info/entry_points.txt +4 -0
  125. omnimancer_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
  126. 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)