empathy-framework 3.7.0__py3-none-any.whl → 3.8.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 (274) hide show
  1. coach_wizards/code_reviewer_README.md +60 -0
  2. coach_wizards/code_reviewer_wizard.py +180 -0
  3. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/METADATA +148 -11
  4. empathy_framework-3.8.0.dist-info/RECORD +333 -0
  5. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/top_level.txt +5 -1
  6. empathy_healthcare_plugin/monitors/__init__.py +9 -0
  7. empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
  8. empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
  9. empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
  10. empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
  11. empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
  12. empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
  13. empathy_llm_toolkit/agent_factory/__init__.py +53 -0
  14. empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
  15. empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
  16. empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
  17. empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
  18. empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
  19. empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
  20. empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
  21. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
  22. empathy_llm_toolkit/agent_factory/base.py +305 -0
  23. empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
  24. empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
  25. empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
  26. empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
  27. empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
  28. empathy_llm_toolkit/agent_factory/decorators.py +286 -0
  29. empathy_llm_toolkit/agent_factory/factory.py +558 -0
  30. empathy_llm_toolkit/agent_factory/framework.py +192 -0
  31. empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
  32. empathy_llm_toolkit/agent_factory/resilient.py +320 -0
  33. empathy_llm_toolkit/cli/__init__.py +8 -0
  34. empathy_llm_toolkit/cli/sync_claude.py +487 -0
  35. empathy_llm_toolkit/code_health.py +150 -3
  36. empathy_llm_toolkit/config/__init__.py +29 -0
  37. empathy_llm_toolkit/config/unified.py +295 -0
  38. empathy_llm_toolkit/routing/__init__.py +32 -0
  39. empathy_llm_toolkit/routing/model_router.py +362 -0
  40. empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
  41. empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
  42. empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
  43. empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
  44. empathy_llm_toolkit/security/README.md +262 -0
  45. empathy_llm_toolkit/security/__init__.py +62 -0
  46. empathy_llm_toolkit/security/audit_logger.py +929 -0
  47. empathy_llm_toolkit/security/audit_logger_example.py +152 -0
  48. empathy_llm_toolkit/security/pii_scrubber.py +640 -0
  49. empathy_llm_toolkit/security/secrets_detector.py +678 -0
  50. empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
  51. empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
  52. empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
  53. empathy_llm_toolkit/wizards/__init__.py +38 -0
  54. empathy_llm_toolkit/wizards/base_wizard.py +364 -0
  55. empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
  56. empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
  57. empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
  58. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
  59. empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
  60. empathy_os/__init__.py +52 -52
  61. empathy_os/adaptive/__init__.py +13 -0
  62. empathy_os/adaptive/task_complexity.py +127 -0
  63. empathy_os/cache/__init__.py +117 -0
  64. empathy_os/cache/base.py +166 -0
  65. empathy_os/cache/dependency_manager.py +253 -0
  66. empathy_os/cache/hash_only.py +248 -0
  67. empathy_os/cache/hybrid.py +390 -0
  68. empathy_os/cache/storage.py +282 -0
  69. empathy_os/cli.py +118 -8
  70. empathy_os/cli_unified.py +121 -1
  71. empathy_os/config/__init__.py +63 -0
  72. empathy_os/config/xml_config.py +239 -0
  73. empathy_os/config.py +2 -1
  74. empathy_os/dashboard/__init__.py +15 -0
  75. empathy_os/dashboard/server.py +743 -0
  76. empathy_os/memory/__init__.py +195 -0
  77. empathy_os/memory/claude_memory.py +466 -0
  78. empathy_os/memory/config.py +224 -0
  79. empathy_os/memory/control_panel.py +1298 -0
  80. empathy_os/memory/edges.py +179 -0
  81. empathy_os/memory/graph.py +567 -0
  82. empathy_os/memory/long_term.py +1194 -0
  83. empathy_os/memory/nodes.py +179 -0
  84. empathy_os/memory/redis_bootstrap.py +540 -0
  85. empathy_os/memory/security/__init__.py +31 -0
  86. empathy_os/memory/security/audit_logger.py +930 -0
  87. empathy_os/memory/security/pii_scrubber.py +640 -0
  88. empathy_os/memory/security/secrets_detector.py +678 -0
  89. empathy_os/memory/short_term.py +2119 -0
  90. empathy_os/memory/storage/__init__.py +15 -0
  91. empathy_os/memory/summary_index.py +583 -0
  92. empathy_os/memory/unified.py +619 -0
  93. empathy_os/metrics/__init__.py +12 -0
  94. empathy_os/metrics/prompt_metrics.py +190 -0
  95. empathy_os/models/__init__.py +136 -0
  96. empathy_os/models/__main__.py +13 -0
  97. empathy_os/models/cli.py +655 -0
  98. empathy_os/models/empathy_executor.py +354 -0
  99. empathy_os/models/executor.py +252 -0
  100. empathy_os/models/fallback.py +671 -0
  101. empathy_os/models/provider_config.py +563 -0
  102. empathy_os/models/registry.py +382 -0
  103. empathy_os/models/tasks.py +302 -0
  104. empathy_os/models/telemetry.py +548 -0
  105. empathy_os/models/token_estimator.py +378 -0
  106. empathy_os/models/validation.py +274 -0
  107. empathy_os/monitoring/__init__.py +52 -0
  108. empathy_os/monitoring/alerts.py +23 -0
  109. empathy_os/monitoring/alerts_cli.py +268 -0
  110. empathy_os/monitoring/multi_backend.py +271 -0
  111. empathy_os/monitoring/otel_backend.py +363 -0
  112. empathy_os/optimization/__init__.py +19 -0
  113. empathy_os/optimization/context_optimizer.py +272 -0
  114. empathy_os/plugins/__init__.py +28 -0
  115. empathy_os/plugins/base.py +361 -0
  116. empathy_os/plugins/registry.py +268 -0
  117. empathy_os/project_index/__init__.py +30 -0
  118. empathy_os/project_index/cli.py +335 -0
  119. empathy_os/project_index/crew_integration.py +430 -0
  120. empathy_os/project_index/index.py +425 -0
  121. empathy_os/project_index/models.py +501 -0
  122. empathy_os/project_index/reports.py +473 -0
  123. empathy_os/project_index/scanner.py +538 -0
  124. empathy_os/prompts/__init__.py +61 -0
  125. empathy_os/prompts/config.py +77 -0
  126. empathy_os/prompts/context.py +177 -0
  127. empathy_os/prompts/parser.py +285 -0
  128. empathy_os/prompts/registry.py +313 -0
  129. empathy_os/prompts/templates.py +208 -0
  130. empathy_os/resilience/__init__.py +56 -0
  131. empathy_os/resilience/circuit_breaker.py +256 -0
  132. empathy_os/resilience/fallback.py +179 -0
  133. empathy_os/resilience/health.py +300 -0
  134. empathy_os/resilience/retry.py +209 -0
  135. empathy_os/resilience/timeout.py +135 -0
  136. empathy_os/routing/__init__.py +43 -0
  137. empathy_os/routing/chain_executor.py +433 -0
  138. empathy_os/routing/classifier.py +217 -0
  139. empathy_os/routing/smart_router.py +234 -0
  140. empathy_os/routing/wizard_registry.py +307 -0
  141. empathy_os/trust/__init__.py +28 -0
  142. empathy_os/trust/circuit_breaker.py +579 -0
  143. empathy_os/validation/__init__.py +19 -0
  144. empathy_os/validation/xml_validator.py +281 -0
  145. empathy_os/wizard_factory_cli.py +170 -0
  146. empathy_os/workflows/__init__.py +360 -0
  147. empathy_os/workflows/base.py +1660 -0
  148. empathy_os/workflows/bug_predict.py +962 -0
  149. empathy_os/workflows/code_review.py +960 -0
  150. empathy_os/workflows/code_review_adapters.py +310 -0
  151. empathy_os/workflows/code_review_pipeline.py +720 -0
  152. empathy_os/workflows/config.py +600 -0
  153. empathy_os/workflows/dependency_check.py +648 -0
  154. empathy_os/workflows/document_gen.py +1069 -0
  155. empathy_os/workflows/documentation_orchestrator.py +1205 -0
  156. empathy_os/workflows/health_check.py +679 -0
  157. empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
  158. empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
  159. empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
  160. empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
  161. empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
  162. empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
  163. empathy_os/workflows/manage_documentation.py +804 -0
  164. empathy_os/workflows/new_sample_workflow1.py +146 -0
  165. empathy_os/workflows/new_sample_workflow1_README.md +150 -0
  166. empathy_os/workflows/perf_audit.py +687 -0
  167. empathy_os/workflows/pr_review.py +748 -0
  168. empathy_os/workflows/progress.py +445 -0
  169. empathy_os/workflows/progress_server.py +322 -0
  170. empathy_os/workflows/refactor_plan.py +693 -0
  171. empathy_os/workflows/release_prep.py +808 -0
  172. empathy_os/workflows/research_synthesis.py +404 -0
  173. empathy_os/workflows/secure_release.py +585 -0
  174. empathy_os/workflows/security_adapters.py +297 -0
  175. empathy_os/workflows/security_audit.py +1046 -0
  176. empathy_os/workflows/step_config.py +234 -0
  177. empathy_os/workflows/test5.py +125 -0
  178. empathy_os/workflows/test5_README.md +158 -0
  179. empathy_os/workflows/test_gen.py +1855 -0
  180. empathy_os/workflows/test_lifecycle.py +526 -0
  181. empathy_os/workflows/test_maintenance.py +626 -0
  182. empathy_os/workflows/test_maintenance_cli.py +590 -0
  183. empathy_os/workflows/test_maintenance_crew.py +821 -0
  184. empathy_os/workflows/xml_enhanced_crew.py +285 -0
  185. empathy_software_plugin/cli/__init__.py +120 -0
  186. empathy_software_plugin/cli/inspect.py +362 -0
  187. empathy_software_plugin/cli.py +3 -1
  188. empathy_software_plugin/wizards/__init__.py +42 -0
  189. empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
  190. empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
  191. empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
  192. empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
  193. empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
  194. empathy_software_plugin/wizards/base_wizard.py +288 -0
  195. empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
  196. empathy_software_plugin/wizards/code_review_wizard.py +606 -0
  197. empathy_software_plugin/wizards/debugging/__init__.py +50 -0
  198. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
  199. empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
  200. empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
  201. empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
  202. empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
  203. empathy_software_plugin/wizards/debugging/verification.py +369 -0
  204. empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
  205. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
  206. empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
  207. empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
  208. empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
  209. empathy_software_plugin/wizards/performance/__init__.py +9 -0
  210. empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
  211. empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
  212. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
  213. empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
  214. empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
  215. empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
  216. empathy_software_plugin/wizards/security/__init__.py +32 -0
  217. empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
  218. empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
  219. empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
  220. empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
  221. empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
  222. empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
  223. empathy_software_plugin/wizards/testing/__init__.py +27 -0
  224. empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
  225. empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
  226. empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
  227. empathy_software_plugin/wizards/testing_wizard.py +274 -0
  228. hot_reload/README.md +473 -0
  229. hot_reload/__init__.py +62 -0
  230. hot_reload/config.py +84 -0
  231. hot_reload/integration.py +228 -0
  232. hot_reload/reloader.py +298 -0
  233. hot_reload/watcher.py +179 -0
  234. hot_reload/websocket.py +176 -0
  235. scaffolding/README.md +589 -0
  236. scaffolding/__init__.py +35 -0
  237. scaffolding/__main__.py +14 -0
  238. scaffolding/cli.py +240 -0
  239. test_generator/__init__.py +38 -0
  240. test_generator/__main__.py +14 -0
  241. test_generator/cli.py +226 -0
  242. test_generator/generator.py +325 -0
  243. test_generator/risk_analyzer.py +216 -0
  244. workflow_patterns/__init__.py +33 -0
  245. workflow_patterns/behavior.py +249 -0
  246. workflow_patterns/core.py +76 -0
  247. workflow_patterns/output.py +99 -0
  248. workflow_patterns/registry.py +255 -0
  249. workflow_patterns/structural.py +288 -0
  250. workflow_scaffolding/__init__.py +11 -0
  251. workflow_scaffolding/__main__.py +12 -0
  252. workflow_scaffolding/cli.py +206 -0
  253. workflow_scaffolding/generator.py +265 -0
  254. agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
  255. agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
  256. agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
  257. agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
  258. agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
  259. agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
  260. agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
  261. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
  262. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
  263. agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
  264. agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
  265. agents/compliance_anticipation_agent.py +0 -1422
  266. agents/compliance_db.py +0 -339
  267. agents/epic_integration_wizard.py +0 -530
  268. agents/notifications.py +0 -291
  269. agents/trust_building_behaviors.py +0 -872
  270. empathy_framework-3.7.0.dist-info/RECORD +0 -105
  271. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/WHEEL +0 -0
  272. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/entry_points.txt +0 -0
  273. {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/licenses/LICENSE +0 -0
  274. /empathy_os/{monitoring.py → agent_monitoring.py} +0 -0
@@ -0,0 +1,286 @@
1
+ """Agent Factory Decorators
2
+
3
+ Standardized decorators for agent operations including error handling,
4
+ logging, and performance monitoring.
5
+
6
+ Copyright 2025 Smart-AI-Memory
7
+ Licensed under Fair Source License 0.9
8
+ """
9
+
10
+ import asyncio
11
+ import logging
12
+ import time
13
+ from collections.abc import Callable
14
+ from functools import wraps
15
+ from typing import Any, TypeVar
16
+
17
+ from empathy_llm_toolkit.config.unified import AgentOperationError
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+ F = TypeVar("F", bound=Callable[..., Any])
22
+
23
+
24
+ def safe_agent_operation(operation_name: str):
25
+ """Decorator for safe agent operations with logging and error handling.
26
+
27
+ Wraps async agent methods to:
28
+ - Log operation start/end
29
+ - Catch and wrap exceptions
30
+ - Add to audit trail if available
31
+ - Provide graceful degradation
32
+
33
+ Args:
34
+ operation_name: Human-readable name for the operation
35
+
36
+ Example:
37
+ class MyAgent(BaseAgent):
38
+ @safe_agent_operation("invoke")
39
+ async def invoke(self, input_data, context=None):
40
+ # Operation code here
41
+ pass
42
+
43
+ """
44
+
45
+ def decorator(func: F) -> F:
46
+ @wraps(func)
47
+ async def wrapper(self, *args, **kwargs):
48
+ start_time = time.time()
49
+ agent_name = getattr(self, "name", self.__class__.__name__)
50
+
51
+ logger.debug(f"[{agent_name}] Starting {operation_name}")
52
+
53
+ try:
54
+ result = await func(self, *args, **kwargs)
55
+
56
+ elapsed = time.time() - start_time
57
+ logger.debug(f"[{agent_name}] Completed {operation_name} in {elapsed:.2f}s")
58
+
59
+ return result
60
+
61
+ except Exception as e:
62
+ elapsed = time.time() - start_time
63
+ logger.error(f"[{agent_name}] {operation_name} failed after {elapsed:.2f}s: {e}")
64
+
65
+ # Add to audit trail if available
66
+ if hasattr(self, "add_audit_entry"):
67
+ state = kwargs.get("state", {})
68
+ if not state and args:
69
+ # Check if first arg is state-like
70
+ if isinstance(args[0], dict):
71
+ state = args[0]
72
+
73
+ try:
74
+ self.add_audit_entry(
75
+ state=state,
76
+ action=f"{operation_name}_error",
77
+ details={
78
+ "error": str(e),
79
+ "error_type": type(e).__name__,
80
+ "elapsed_seconds": elapsed,
81
+ },
82
+ )
83
+ except Exception:
84
+ pass # Don't fail on audit trail errors
85
+
86
+ raise AgentOperationError(operation_name, e) from e
87
+
88
+ return wrapper # type: ignore
89
+
90
+ return decorator
91
+
92
+
93
+ def retry_on_failure(
94
+ max_attempts: int = 3,
95
+ delay: float = 1.0,
96
+ backoff: float = 2.0,
97
+ exceptions: tuple = (Exception,),
98
+ ):
99
+ """Decorator to retry failed operations with exponential backoff.
100
+
101
+ Args:
102
+ max_attempts: Maximum number of attempts
103
+ delay: Initial delay between retries (seconds)
104
+ backoff: Multiplier for delay after each retry
105
+ exceptions: Tuple of exception types to catch and retry
106
+
107
+ Example:
108
+ @retry_on_failure(max_attempts=3, delay=1.0)
109
+ async def call_external_api(self):
110
+ # Flaky operation
111
+ pass
112
+
113
+ """
114
+
115
+ def decorator(func: F) -> F:
116
+ @wraps(func)
117
+ async def wrapper(*args, **kwargs):
118
+ last_exception = None
119
+ current_delay = delay
120
+
121
+ for attempt in range(max_attempts):
122
+ try:
123
+ return await func(*args, **kwargs)
124
+ except exceptions as e:
125
+ last_exception = e
126
+ if attempt < max_attempts - 1:
127
+ logger.warning(
128
+ f"Attempt {attempt + 1}/{max_attempts} failed: {e}. "
129
+ f"Retrying in {current_delay:.1f}s...",
130
+ )
131
+ await asyncio.sleep(current_delay)
132
+ current_delay *= backoff
133
+ else:
134
+ logger.error(f"All {max_attempts} attempts failed. Last error: {e}")
135
+
136
+ raise last_exception
137
+
138
+ return wrapper # type: ignore
139
+
140
+ return decorator
141
+
142
+
143
+ def log_performance(threshold_seconds: float = 1.0):
144
+ """Decorator to log slow operations.
145
+
146
+ Args:
147
+ threshold_seconds: Log warning if operation exceeds this duration
148
+
149
+ Example:
150
+ @log_performance(threshold_seconds=2.0)
151
+ async def heavy_computation(self):
152
+ # Potentially slow operation
153
+ pass
154
+
155
+ """
156
+
157
+ def decorator(func: F) -> F:
158
+ @wraps(func)
159
+ async def wrapper(*args, **kwargs):
160
+ start_time = time.time()
161
+
162
+ result = await func(*args, **kwargs)
163
+
164
+ elapsed = time.time() - start_time
165
+ func_name = func.__name__
166
+
167
+ if elapsed > threshold_seconds:
168
+ logger.warning(
169
+ f"Slow operation: {func_name} took {elapsed:.2f}s "
170
+ f"(threshold: {threshold_seconds}s)",
171
+ )
172
+ else:
173
+ logger.debug(f"{func_name} completed in {elapsed:.2f}s")
174
+
175
+ return result
176
+
177
+ return wrapper # type: ignore
178
+
179
+ return decorator
180
+
181
+
182
+ def validate_input(required_fields: list[str]):
183
+ """Decorator to validate required fields in input data.
184
+
185
+ Args:
186
+ required_fields: List of required field names
187
+
188
+ Example:
189
+ @validate_input(["query", "context"])
190
+ async def process(self, input_data: dict):
191
+ # input_data is guaranteed to have query and context
192
+ pass
193
+
194
+ """
195
+
196
+ def decorator(func: F) -> F:
197
+ @wraps(func)
198
+ async def wrapper(self, input_data, *args, **kwargs):
199
+ if not isinstance(input_data, dict):
200
+ raise ValueError(f"Input must be a dict, got {type(input_data).__name__}")
201
+
202
+ missing = [f for f in required_fields if f not in input_data]
203
+ if missing:
204
+ raise ValueError(f"Missing required fields: {missing}")
205
+
206
+ return await func(self, input_data, *args, **kwargs)
207
+
208
+ return wrapper # type: ignore
209
+
210
+ return decorator
211
+
212
+
213
+ def with_cost_tracking(operation_type: str = "agent_call"):
214
+ """Decorator to track API costs for operations.
215
+
216
+ Args:
217
+ operation_type: Type of operation for cost categorization
218
+
219
+ Example:
220
+ @with_cost_tracking(operation_type="research")
221
+ async def research(self, query: str):
222
+ # LLM call that should be tracked
223
+ pass
224
+
225
+ """
226
+
227
+ def decorator(func: F) -> F:
228
+ @wraps(func)
229
+ async def wrapper(self, *args, **kwargs):
230
+ # Record start
231
+ operation_id = f"{operation_type}_{time.time_ns()}"
232
+
233
+ result = await func(self, *args, **kwargs)
234
+
235
+ # Extract token usage if available
236
+ if isinstance(result, dict):
237
+ metadata = result.get("metadata", {})
238
+ tokens_used = metadata.get("tokens_used", 0)
239
+ model = metadata.get("model", "unknown")
240
+
241
+ # Log for cost tracking
242
+ if hasattr(self, "_track_cost"):
243
+ self._track_cost(
244
+ operation_id=operation_id,
245
+ operation_type=operation_type,
246
+ model=model,
247
+ tokens=tokens_used,
248
+ )
249
+
250
+ return result
251
+
252
+ return wrapper # type: ignore
253
+
254
+ return decorator
255
+
256
+
257
+ def graceful_degradation(fallback_value: Any = None, log_level: str = "warning"):
258
+ """Decorator for graceful degradation on failure.
259
+
260
+ Instead of raising an exception, returns a fallback value.
261
+
262
+ Args:
263
+ fallback_value: Value to return on failure
264
+ log_level: Log level for the failure message
265
+
266
+ Example:
267
+ @graceful_degradation(fallback_value=[], log_level="warning")
268
+ async def get_optional_data(self):
269
+ # If this fails, return empty list instead of crashing
270
+ pass
271
+
272
+ """
273
+
274
+ def decorator(func: F) -> F:
275
+ @wraps(func)
276
+ async def wrapper(*args, **kwargs):
277
+ try:
278
+ return await func(*args, **kwargs)
279
+ except Exception as e:
280
+ log_func = getattr(logger, log_level.lower(), logger.warning)
281
+ log_func(f"{func.__name__} failed, using fallback: {e}")
282
+ return fallback_value
283
+
284
+ return wrapper # type: ignore
285
+
286
+ return decorator