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,540 @@
1
+ """
2
+ Status-Integrated Agent Engine for Omnimancer.
3
+
4
+ This module provides an enhanced AgentEngine that integrates with the status
5
+ tracking and display system, providing real-time updates on agent operations
6
+ and state changes.
7
+ """
8
+
9
+ import logging
10
+ import uuid
11
+ from datetime import datetime
12
+ from pathlib import Path
13
+ from typing import Any, Dict, Optional
14
+
15
+ from ..agent_engine import AgentEngine
16
+ from ..config_manager import ConfigManager
17
+ from .status_core import (
18
+ AgentOperation,
19
+ AgentStatus,
20
+ )
21
+ from .status_core import OperationType as StatusOperationType
22
+ from .status_manager import UnifiedStatusManager as AgentStatusManager
23
+ from .status_manager import (
24
+ get_status_manager,
25
+ )
26
+ from .types import Operation, OperationResult, OperationType
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ class StatusIntegratedAgentEngine(AgentEngine):
32
+ """
33
+ Agent engine enhanced with comprehensive status tracking and display.
34
+
35
+ This class extends the base AgentEngine to provide real-time status updates,
36
+ operation tracking, and integration with the status display system.
37
+ """
38
+
39
+ def __init__(
40
+ self,
41
+ config_manager: ConfigManager,
42
+ base_path: Optional[Path] = None,
43
+ status_manager: Optional[AgentStatusManager] = None,
44
+ enable_status_display: bool = True,
45
+ ):
46
+ """
47
+ Initialize the status-integrated agent engine.
48
+
49
+ Args:
50
+ config_manager: Configuration manager instance
51
+ base_path: Base path for file system operations
52
+ status_manager: Optional status manager (uses global if not provided)
53
+ enable_status_display: Whether to enable status display
54
+ """
55
+ super().__init__(config_manager, base_path)
56
+
57
+ # Status system integration
58
+ self.status_manager = status_manager or get_status_manager()
59
+ self.enable_status_display = enable_status_display
60
+
61
+ # Operation mapping for status tracking
62
+ self.operation_mapping = {
63
+ OperationType.FILE_READ: StatusOperationType.FILE_READ,
64
+ OperationType.FILE_WRITE: StatusOperationType.FILE_WRITE,
65
+ OperationType.FILE_DELETE: StatusOperationType.FILE_DELETE,
66
+ OperationType.DIRECTORY_CREATE: StatusOperationType.DIRECTORY_CREATE,
67
+ OperationType.DIRECTORY_DELETE: StatusOperationType.DIRECTORY_DELETE,
68
+ OperationType.COMMAND_EXECUTION: StatusOperationType.COMMAND_EXECUTION,
69
+ OperationType.WEB_REQUEST: StatusOperationType.WEB_REQUEST,
70
+ OperationType.API_CALL: StatusOperationType.API_CALL,
71
+ OperationType.APPROVAL_REQUEST: StatusOperationType.APPROVAL_REQUEST,
72
+ }
73
+
74
+ # Active operation tracking
75
+ self.active_status_operations: Dict[str, str] = (
76
+ {}
77
+ ) # agent_operation_id -> status_operation_id
78
+
79
+ # Agent identification
80
+ self.agent_id = "main_agent" # Could be made configurable
81
+
82
+ logger.info(
83
+ "StatusIntegratedAgentEngine initialized with status tracking enabled"
84
+ )
85
+
86
+ async def initialize_status_system(self) -> None:
87
+ """Initialize the integrated status system."""
88
+ try:
89
+ # Initialize status manager
90
+ await self.status_manager.initialize()
91
+
92
+ # Set initial agent status
93
+ await self.status_manager.set_agent_status(
94
+ self.agent_id,
95
+ AgentStatus.ENABLED,
96
+ {
97
+ "initialization_time": datetime.now(),
98
+ "engine_type": "StatusIntegratedAgentEngine",
99
+ "base_path": (
100
+ str(self.file_system.base_path)
101
+ if hasattr(self, "file_system")
102
+ else None
103
+ ),
104
+ },
105
+ )
106
+
107
+ logger.info(f"Status system initialized for agent {self.agent_id}")
108
+
109
+ except Exception as e:
110
+ logger.error(f"Failed to initialize status system: {e}")
111
+ # Don't fail the entire engine if status system fails
112
+ self.enable_status_display = False
113
+
114
+ async def shutdown_status_system(self) -> None:
115
+ """Shutdown the integrated status system."""
116
+ try:
117
+ # Set agent status to shutting down
118
+ await self.status_manager.set_agent_status(
119
+ self.agent_id,
120
+ AgentStatus.SHUTTING_DOWN,
121
+ {"shutdown_time": datetime.now()},
122
+ )
123
+
124
+ # Cancel any active operations
125
+ for agent_op_id, status_op_id in list(
126
+ self.active_status_operations.items()
127
+ ):
128
+ await self.status_manager.cancel_operation(
129
+ status_op_id, "Engine shutdown"
130
+ )
131
+
132
+ # Shutdown status manager
133
+ await self.status_manager.shutdown()
134
+
135
+ logger.info("Status system shutdown complete")
136
+
137
+ except Exception as e:
138
+ logger.error(f"Error during status system shutdown: {e}")
139
+
140
+ async def execute_with_approval(self, operation: Operation) -> OperationResult:
141
+ """
142
+ Execute operation with approval workflow and status tracking.
143
+
144
+ Args:
145
+ operation: Operation to execute
146
+
147
+ Returns:
148
+ Result of the operation
149
+ """
150
+ status_operation = None
151
+
152
+ try:
153
+ # Create status operation for tracking
154
+ if self.enable_status_display:
155
+ status_operation = await self._create_status_operation(operation)
156
+
157
+ # Set agent to running state
158
+ if self.enable_status_display:
159
+ await self.status_manager.set_agent_status(
160
+ self.agent_id,
161
+ AgentStatus.RUNNING,
162
+ {
163
+ "current_operation": (
164
+ operation.type.value
165
+ if hasattr(operation.type, "value")
166
+ else str(operation.type)
167
+ )
168
+ },
169
+ )
170
+
171
+ # Execute the operation using parent class method
172
+ result = await super().execute_with_approval(operation)
173
+
174
+ # Update status based on result
175
+ if self.enable_status_display and status_operation:
176
+ if result.success:
177
+ await self.status_manager.complete_operation(
178
+ status_operation.operation_id,
179
+ {
180
+ "result_data": result.data,
181
+ "execution_details": result.details,
182
+ },
183
+ )
184
+ else:
185
+ await self.status_manager.fail_operation(
186
+ status_operation.operation_id,
187
+ result.error or "Operation failed without specific error",
188
+ {
189
+ "error_details": result.details,
190
+ "failure_context": result.error,
191
+ },
192
+ )
193
+
194
+ # Set agent back to enabled state
195
+ if self.enable_status_display:
196
+ await self.status_manager.set_agent_status(
197
+ self.agent_id,
198
+ AgentStatus.ENABLED,
199
+ {
200
+ "last_operation_result": (
201
+ "success" if result.success else "failed"
202
+ )
203
+ },
204
+ )
205
+
206
+ return result
207
+
208
+ except Exception as e:
209
+ # Handle operation failure in status system
210
+ if self.enable_status_display and status_operation:
211
+ await self.status_manager.fail_operation(
212
+ status_operation.operation_id,
213
+ f"Exception during execution: {e}",
214
+ {
215
+ "exception_type": type(e).__name__,
216
+ "exception_details": str(e),
217
+ },
218
+ )
219
+
220
+ # Set agent to error state
221
+ if self.enable_status_display:
222
+ await self.status_manager.set_agent_status(
223
+ self.agent_id,
224
+ AgentStatus.ERROR,
225
+ {"error_message": str(e), "error_time": datetime.now()},
226
+ )
227
+
228
+ # Re-raise the exception
229
+ raise
230
+ finally:
231
+ # Clean up operation tracking
232
+ if status_operation and operation.id in self.active_status_operations:
233
+ del self.active_status_operations[operation.id]
234
+
235
+ async def _create_status_operation(self, operation: Operation) -> AgentOperation:
236
+ """
237
+ Create a status operation for tracking.
238
+
239
+ Args:
240
+ operation: The agent operation to track
241
+
242
+ Returns:
243
+ Created status operation
244
+ """
245
+ # Map operation type
246
+ status_op_type = self.operation_mapping.get(
247
+ operation.type, StatusOperationType.API_CALL
248
+ )
249
+
250
+ # Create operation description
251
+ description = self._generate_operation_description(operation)
252
+
253
+ # Create status operation
254
+ status_operation = AgentOperation(
255
+ operation_id=str(uuid.uuid4()),
256
+ operation_type=status_op_type,
257
+ description=description,
258
+ agent_id=self.agent_id,
259
+ metadata={
260
+ "original_operation_id": operation.id,
261
+ "original_operation_type": (
262
+ operation.type.value
263
+ if hasattr(operation.type, "value")
264
+ else str(operation.type)
265
+ ),
266
+ "operation_data": operation.data,
267
+ "requires_approval": operation.requires_approval,
268
+ },
269
+ )
270
+
271
+ # Start tracking
272
+ await self.status_manager.start_operation(status_operation)
273
+
274
+ # Keep reference for updates
275
+ self.active_status_operations[operation.id] = status_operation.operation_id
276
+
277
+ return status_operation
278
+
279
+ def _generate_operation_description(self, operation: Operation) -> str:
280
+ """
281
+ Generate a user-friendly description for an operation.
282
+
283
+ Args:
284
+ operation: The operation to describe
285
+
286
+ Returns:
287
+ Human-readable description
288
+ """
289
+ op_type = operation.type
290
+ data = operation.data
291
+
292
+ try:
293
+ if hasattr(op_type, "value"):
294
+ type_str = op_type.value
295
+ else:
296
+ type_str = str(op_type)
297
+
298
+ if type_str == "FILE_READ" and "path" in data:
299
+ return f"Reading file: {Path(data['path']).name}"
300
+ elif type_str == "FILE_WRITE" and "path" in data:
301
+ return f"Writing to file: {Path(data['path']).name}"
302
+ elif type_str == "FILE_DELETE" and "path" in data:
303
+ return f"Deleting file: {Path(data['path']).name}"
304
+ elif type_str == "DIRECTORY_CREATE" and "path" in data:
305
+ return f"Creating directory: {Path(data['path']).name}"
306
+ elif type_str == "DIRECTORY_DELETE" and "path" in data:
307
+ return f"Deleting directory: {Path(data['path']).name}"
308
+ elif type_str == "COMMAND_EXECUTION" and "command" in data:
309
+ cmd = data["command"]
310
+ return f"Executing: {cmd[:30]}{'...' if len(cmd) > 30 else ''}"
311
+ elif type_str == "WEB_REQUEST" and "url" in data:
312
+ return f"Web request to: {data['url']}"
313
+ elif type_str == "API_CALL":
314
+ return "Making API call"
315
+ elif type_str == "APPROVAL_REQUEST":
316
+ return "Requesting user approval"
317
+ else:
318
+ return f"Executing {type_str.lower().replace('_', ' ')}"
319
+
320
+ except Exception as e:
321
+ logger.warning(f"Failed to generate operation description: {e}")
322
+ return f"Executing {type_str.lower().replace('_', ' ') if type_str else 'operation'}"
323
+
324
+ async def update_operation_progress(
325
+ self,
326
+ operation_id: str,
327
+ progress: float,
328
+ description: Optional[str] = None,
329
+ ) -> None:
330
+ """
331
+ Update progress of an operation.
332
+
333
+ Args:
334
+ operation_id: ID of the agent operation
335
+ progress: Progress percentage (0-100)
336
+ description: Optional progress description
337
+ """
338
+ if (
339
+ not self.enable_status_display
340
+ or operation_id not in self.active_status_operations
341
+ ):
342
+ return
343
+
344
+ status_operation_id = self.active_status_operations[operation_id]
345
+
346
+ try:
347
+ await self.status_manager.update_operation_progress(
348
+ status_operation_id, progress, description
349
+ )
350
+ except Exception as e:
351
+ logger.error(f"Failed to update operation progress: {e}")
352
+
353
+ async def get_status_summary(self) -> Dict[str, Any]:
354
+ """
355
+ Get a summary of current agent status.
356
+
357
+ Returns:
358
+ Dictionary with status information
359
+ """
360
+ if not self.enable_status_display:
361
+ return {"status_display": "disabled"}
362
+
363
+ try:
364
+ agent_status = self.status_manager.get_agent_status(self.agent_id)
365
+ agent_metadata = self.status_manager.get_agent_metadata(self.agent_id)
366
+ active_operations = self.status_manager.get_active_operations(self.agent_id)
367
+ system_stats = self.status_manager.get_stats()
368
+
369
+ return {
370
+ "agent_id": self.agent_id,
371
+ "status": agent_status.value if agent_status else "unknown",
372
+ "metadata": agent_metadata,
373
+ "active_operations_count": len(active_operations),
374
+ "active_operations": [
375
+ {
376
+ "id": op.operation_id,
377
+ "type": op.operation_type.value,
378
+ "description": op.description,
379
+ "progress": op.progress_percentage,
380
+ "duration": (op.duration.total_seconds() if op.duration else 0),
381
+ }
382
+ for op in active_operations
383
+ ],
384
+ "system_stats": system_stats,
385
+ "status_stream_running": self.status_manager.running,
386
+ }
387
+
388
+ except Exception as e:
389
+ logger.error(f"Failed to get status summary: {e}")
390
+ return {"error": f"Failed to get status: {e}"}
391
+
392
+ def is_status_display_enabled(self) -> bool:
393
+ """Check if status display is enabled."""
394
+ return self.enable_status_display
395
+
396
+ def enable_status_display_mode(self) -> None:
397
+ """Enable status display mode."""
398
+ self.enable_status_display = True
399
+
400
+ def disable_status_display_mode(self) -> None:
401
+ """Disable status display mode."""
402
+ self.enable_status_display = False
403
+
404
+ async def start_status_monitoring(self) -> bool:
405
+ """
406
+ Start status monitoring and display.
407
+
408
+ Returns:
409
+ True if monitoring started successfully
410
+ """
411
+ try:
412
+ if not self.enable_status_display:
413
+ return False
414
+
415
+ # Initialize if not already done
416
+ if not self.status_manager._event_processor_task:
417
+ await self.status_manager.initialize()
418
+
419
+ # Status manager handles stream initialization
420
+
421
+ logger.info("Status monitoring started successfully")
422
+ return True
423
+
424
+ except Exception as e:
425
+ logger.error(f"Failed to start status monitoring: {e}")
426
+ return False
427
+
428
+ async def stop_status_monitoring(self) -> bool:
429
+ """
430
+ Stop status monitoring and display.
431
+
432
+ Returns:
433
+ True if monitoring stopped successfully
434
+ """
435
+ try:
436
+ # The unified status manager handles stream shutdown
437
+
438
+ # Update agent status
439
+ await self.status_manager.set_agent_status(
440
+ self.agent_id,
441
+ AgentStatus.DISABLED,
442
+ {"monitoring_stopped": datetime.now()},
443
+ )
444
+
445
+ logger.info("Status monitoring stopped successfully")
446
+ return True
447
+
448
+ except Exception as e:
449
+ logger.error(f"Failed to stop status monitoring: {e}")
450
+ return False
451
+
452
+
453
+ # Factory function to create a fully integrated engine
454
+ async def create_status_integrated_engine(
455
+ config_manager: ConfigManager,
456
+ base_path: Optional[Path] = None,
457
+ auto_initialize: bool = True,
458
+ ) -> StatusIntegratedAgentEngine:
459
+ """
460
+ Create a status-integrated agent engine with automatic setup.
461
+
462
+ Args:
463
+ config_manager: Configuration manager instance
464
+ base_path: Base path for file system operations
465
+ auto_initialize: Whether to automatically initialize the status system
466
+
467
+ Returns:
468
+ Fully configured status-integrated engine
469
+ """
470
+ # Create engine
471
+ engine = StatusIntegratedAgentEngine(config_manager, base_path)
472
+
473
+ # Auto-initialize if requested
474
+ if auto_initialize:
475
+ try:
476
+ await engine.initialize_status_system()
477
+ await engine.start_status_monitoring()
478
+ logger.info("Status-integrated engine created and initialized")
479
+ except Exception as e:
480
+ logger.error(f"Failed to auto-initialize status system: {e}")
481
+ # Continue with engine creation but status display disabled
482
+ engine.disable_status_display_mode()
483
+
484
+ return engine
485
+
486
+
487
+ # Context manager for temporary status tracking
488
+ class StatusTrackingContext:
489
+ """Context manager for temporary status tracking within operations."""
490
+
491
+ def __init__(self, engine: StatusIntegratedAgentEngine, operation_name: str):
492
+ self.engine = engine
493
+ self.operation_name = operation_name
494
+ self.operation_id = None
495
+
496
+ async def __aenter__(self):
497
+ if self.engine.enable_status_display:
498
+ # Create a temporary operation
499
+ from .types import Operation as TempOperation
500
+ from .types import OperationType as TempOperationType
501
+
502
+ temp_operation = TempOperation(
503
+ id=str(uuid.uuid4()),
504
+ type=TempOperationType.API_CALL, # Generic type
505
+ data={"description": self.operation_name},
506
+ requires_approval=False,
507
+ )
508
+
509
+ await self.engine._create_status_operation(temp_operation)
510
+ self.operation_id = temp_operation.id
511
+
512
+ return self
513
+
514
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
515
+ if self.engine.enable_status_display and self.operation_id:
516
+ status_operation_id = self.engine.active_status_operations.get(
517
+ self.operation_id
518
+ )
519
+ if status_operation_id:
520
+ if exc_type:
521
+ await self.engine.status_manager.fail_operation(
522
+ status_operation_id,
523
+ f"Context operation failed: {exc_val}",
524
+ {"exception_type": exc_type.__name__},
525
+ )
526
+ else:
527
+ await self.engine.status_manager.complete_operation(
528
+ status_operation_id, {"context_result": "success"}
529
+ )
530
+
531
+ # Clean up
532
+ if self.operation_id in self.engine.active_status_operations:
533
+ del self.engine.active_status_operations[self.operation_id]
534
+
535
+ async def update_progress(self, progress: float, description: Optional[str] = None):
536
+ """Update progress of the tracked operation."""
537
+ if self.operation_id:
538
+ await self.engine.update_operation_progress(
539
+ self.operation_id, progress, description
540
+ )