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,174 @@
1
+ """
2
+ Signal handling for graceful shutdown of Omnimancer.
3
+
4
+ This module provides signal handling functionality to allow users to
5
+ exit Omnimancer gracefully with Ctrl+C, including cancellation of active
6
+ operations and proper resource cleanup.
7
+ """
8
+
9
+ import asyncio
10
+ import logging
11
+ import os
12
+ import signal
13
+ from typing import Set
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class SignalHandler:
19
+ """
20
+ Handles signal-based shutdown for Omnimancer application.
21
+
22
+ This class manages SIGINT (Ctrl+C) and SIGTERM signals to provide
23
+ graceful shutdown functionality including:
24
+ - Cancellation of active operations
25
+ - Cleanup of agent resources
26
+ - Force exit on double Ctrl+C
27
+ """
28
+
29
+ def __init__(self, agent_engine=None):
30
+ """
31
+ Initialize the SignalHandler.
32
+
33
+ Args:
34
+ agent_engine: Optional agent engine instance for cleanup
35
+ """
36
+ self.agent_engine = agent_engine
37
+ self.shutdown_event = asyncio.Event()
38
+ self.active_operations: Set[asyncio.Task] = set()
39
+ self.shutdown_in_progress = False
40
+ logger.debug("SignalHandler initialized")
41
+
42
+ def setup_signal_handlers(self) -> None:
43
+ """
44
+ Register SIGINT (Ctrl+C) and SIGTERM handlers.
45
+
46
+ This method sets up the signal handlers that will be called
47
+ when the user presses Ctrl+C or when the process receives
48
+ a SIGTERM signal.
49
+ """
50
+ try:
51
+ signal.signal(signal.SIGINT, self._handle_interrupt)
52
+ signal.signal(signal.SIGTERM, self._handle_interrupt)
53
+ logger.info("Signal handlers registered for SIGINT and SIGTERM")
54
+ except ValueError as e:
55
+ # This can happen if signal handlers are set up on a thread
56
+ # other than the main thread
57
+ logger.warning(f"Failed to register signal handlers: {e}")
58
+
59
+ def _handle_interrupt(self, signum: int, frame) -> None:
60
+ """
61
+ Handle interrupt signals gracefully.
62
+
63
+ This method is called when SIGINT or SIGTERM is received.
64
+ On the first signal, it initiates graceful shutdown.
65
+ On the second signal, it forces immediate exit.
66
+
67
+ Args:
68
+ signum: Signal number
69
+ frame: Current stack frame
70
+ """
71
+ signal_name = "SIGINT" if signum == signal.SIGINT else "SIGTERM"
72
+ logger.debug(f"Received {signal_name} signal")
73
+
74
+ if self.shutdown_in_progress:
75
+ # Force exit on second Ctrl+C
76
+ print("\nForce exit requested. Terminating immediately...")
77
+ logger.info("Force exit requested, terminating immediately")
78
+ os._exit(1)
79
+
80
+ self.shutdown_in_progress = True
81
+ print("\nShutdown requested. Canceling operations...")
82
+ logger.info("Graceful shutdown initiated")
83
+
84
+ # Create shutdown task in the event loop
85
+ try:
86
+ loop = asyncio.get_event_loop()
87
+ if loop.is_running():
88
+ loop.create_task(self._graceful_shutdown())
89
+ else:
90
+ logger.warning("Event loop is not running, cannot create shutdown task")
91
+ except RuntimeError:
92
+ # No event loop running, exit immediately
93
+ logger.warning("No event loop available, exiting immediately")
94
+ os._exit(1)
95
+
96
+ async def _graceful_shutdown(self) -> None:
97
+ """
98
+ Cancel active operations and shutdown gracefully.
99
+
100
+ This method:
101
+ 1. Cancels all active operations
102
+ 2. Waits for operations to complete (with timeout)
103
+ 3. Cleans up agent resources
104
+ 4. Sets the shutdown event
105
+ """
106
+ logger.info("Starting graceful shutdown process")
107
+
108
+ # Cancel all active operations
109
+ cancelled_count = 0
110
+ for task in self.active_operations.copy():
111
+ if not task.done():
112
+ task.cancel()
113
+ cancelled_count += 1
114
+
115
+ if cancelled_count > 0:
116
+ logger.info(f"Cancelled {cancelled_count} active operations")
117
+
118
+ # Wait for operations to complete or timeout
119
+ if self.active_operations:
120
+ print(
121
+ f"Waiting for {len(self.active_operations)} operations to complete..."
122
+ )
123
+ try:
124
+ await asyncio.wait_for(
125
+ asyncio.gather(*self.active_operations, return_exceptions=True),
126
+ timeout=5.0,
127
+ )
128
+ logger.info("All operations completed successfully")
129
+ except asyncio.TimeoutError:
130
+ print("Timeout waiting for operations to complete. Forcing shutdown...")
131
+ logger.warning("Timeout during graceful shutdown, forcing exit")
132
+
133
+ # Cleanup agent resources
134
+ if self.agent_engine and hasattr(self.agent_engine, "cleanup"):
135
+ try:
136
+ await self.agent_engine.cleanup()
137
+ logger.info("Agent engine cleanup completed")
138
+ except Exception as e:
139
+ logger.error(f"Error during agent engine cleanup: {e}")
140
+
141
+ # Signal shutdown completion
142
+ self.shutdown_event.set()
143
+ logger.info("Graceful shutdown completed")
144
+
145
+ def register_operation(self, task: asyncio.Task) -> None:
146
+ """
147
+ Register an active operation for tracking.
148
+
149
+ Registered operations will be cancelled during shutdown
150
+ and automatically removed when they complete.
151
+
152
+ Args:
153
+ task: Asyncio task to track
154
+ """
155
+ if task.done():
156
+ logger.debug("Attempted to register already completed task")
157
+ return
158
+
159
+ self.active_operations.add(task)
160
+ task.add_done_callback(self.active_operations.discard)
161
+ logger.debug(
162
+ f"Registered operation, total active: {len(self.active_operations)}"
163
+ )
164
+
165
+ async def wait_for_shutdown(self) -> None:
166
+ """
167
+ Wait for shutdown signal.
168
+
169
+ This method blocks until a shutdown signal is received
170
+ and the graceful shutdown process is complete.
171
+ """
172
+ logger.debug("Waiting for shutdown signal")
173
+ await self.shutdown_event.wait()
174
+ logger.info("Shutdown signal received")
@@ -0,0 +1,11 @@
1
+ """
2
+ MCP (Model Context Protocol) integration for Omnimancer.
3
+
4
+ This module provides MCP server integration capabilities including
5
+ server connection management, tool discovery, and tool execution.
6
+ """
7
+
8
+ from .client import MCPClient
9
+ from .manager import MCPManager
10
+
11
+ __all__ = ["MCPClient", "MCPManager"]