empathy-framework 2.4.0__py3-none-any.whl → 3.8.2__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 (329) hide show
  1. coach_wizards/__init__.py +13 -12
  2. coach_wizards/accessibility_wizard.py +12 -12
  3. coach_wizards/api_wizard.py +12 -12
  4. coach_wizards/base_wizard.py +26 -20
  5. coach_wizards/cicd_wizard.py +15 -13
  6. coach_wizards/code_reviewer_README.md +60 -0
  7. coach_wizards/code_reviewer_wizard.py +180 -0
  8. coach_wizards/compliance_wizard.py +12 -12
  9. coach_wizards/database_wizard.py +12 -12
  10. coach_wizards/debugging_wizard.py +12 -12
  11. coach_wizards/documentation_wizard.py +12 -12
  12. coach_wizards/generate_wizards.py +1 -2
  13. coach_wizards/localization_wizard.py +101 -19
  14. coach_wizards/migration_wizard.py +12 -12
  15. coach_wizards/monitoring_wizard.py +12 -12
  16. coach_wizards/observability_wizard.py +12 -12
  17. coach_wizards/performance_wizard.py +12 -12
  18. coach_wizards/prompt_engineering_wizard.py +661 -0
  19. coach_wizards/refactoring_wizard.py +12 -12
  20. coach_wizards/scaling_wizard.py +12 -12
  21. coach_wizards/security_wizard.py +12 -12
  22. coach_wizards/testing_wizard.py +12 -12
  23. empathy_framework-3.8.2.dist-info/METADATA +1176 -0
  24. empathy_framework-3.8.2.dist-info/RECORD +333 -0
  25. empathy_framework-3.8.2.dist-info/entry_points.txt +22 -0
  26. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/top_level.txt +5 -1
  27. empathy_healthcare_plugin/__init__.py +1 -2
  28. empathy_healthcare_plugin/monitors/__init__.py +9 -0
  29. empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
  30. empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
  31. empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
  32. empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
  33. empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
  34. empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
  35. empathy_llm_toolkit/__init__.py +7 -7
  36. empathy_llm_toolkit/agent_factory/__init__.py +53 -0
  37. empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
  38. empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
  39. empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
  40. empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
  41. empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
  42. empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
  43. empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
  44. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
  45. empathy_llm_toolkit/agent_factory/base.py +305 -0
  46. empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
  47. empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
  48. empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
  49. empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
  50. empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
  51. empathy_llm_toolkit/agent_factory/decorators.py +286 -0
  52. empathy_llm_toolkit/agent_factory/factory.py +558 -0
  53. empathy_llm_toolkit/agent_factory/framework.py +192 -0
  54. empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
  55. empathy_llm_toolkit/agent_factory/resilient.py +320 -0
  56. empathy_llm_toolkit/claude_memory.py +14 -15
  57. empathy_llm_toolkit/cli/__init__.py +8 -0
  58. empathy_llm_toolkit/cli/sync_claude.py +487 -0
  59. empathy_llm_toolkit/code_health.py +186 -28
  60. empathy_llm_toolkit/config/__init__.py +29 -0
  61. empathy_llm_toolkit/config/unified.py +295 -0
  62. empathy_llm_toolkit/contextual_patterns.py +11 -12
  63. empathy_llm_toolkit/core.py +168 -53
  64. empathy_llm_toolkit/git_pattern_extractor.py +17 -13
  65. empathy_llm_toolkit/levels.py +6 -13
  66. empathy_llm_toolkit/pattern_confidence.py +14 -18
  67. empathy_llm_toolkit/pattern_resolver.py +10 -12
  68. empathy_llm_toolkit/pattern_summary.py +16 -14
  69. empathy_llm_toolkit/providers.py +194 -28
  70. empathy_llm_toolkit/routing/__init__.py +32 -0
  71. empathy_llm_toolkit/routing/model_router.py +362 -0
  72. empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
  73. empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
  74. empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
  75. empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
  76. empathy_llm_toolkit/security/README.md +262 -0
  77. empathy_llm_toolkit/security/__init__.py +62 -0
  78. empathy_llm_toolkit/security/audit_logger.py +929 -0
  79. empathy_llm_toolkit/security/audit_logger_example.py +152 -0
  80. empathy_llm_toolkit/security/pii_scrubber.py +640 -0
  81. empathy_llm_toolkit/security/secrets_detector.py +678 -0
  82. empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
  83. empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
  84. empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
  85. empathy_llm_toolkit/session_status.py +20 -22
  86. empathy_llm_toolkit/state.py +28 -21
  87. empathy_llm_toolkit/wizards/__init__.py +38 -0
  88. empathy_llm_toolkit/wizards/base_wizard.py +364 -0
  89. empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
  90. empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
  91. empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
  92. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
  93. empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
  94. empathy_os/__init__.py +125 -84
  95. empathy_os/adaptive/__init__.py +13 -0
  96. empathy_os/adaptive/task_complexity.py +127 -0
  97. empathy_os/{monitoring.py → agent_monitoring.py} +28 -28
  98. empathy_os/cache/__init__.py +117 -0
  99. empathy_os/cache/base.py +166 -0
  100. empathy_os/cache/dependency_manager.py +253 -0
  101. empathy_os/cache/hash_only.py +248 -0
  102. empathy_os/cache/hybrid.py +390 -0
  103. empathy_os/cache/storage.py +282 -0
  104. empathy_os/cli.py +1516 -70
  105. empathy_os/cli_unified.py +597 -0
  106. empathy_os/config/__init__.py +63 -0
  107. empathy_os/config/xml_config.py +239 -0
  108. empathy_os/config.py +95 -37
  109. empathy_os/coordination.py +72 -68
  110. empathy_os/core.py +94 -107
  111. empathy_os/cost_tracker.py +74 -55
  112. empathy_os/dashboard/__init__.py +15 -0
  113. empathy_os/dashboard/server.py +743 -0
  114. empathy_os/discovery.py +17 -14
  115. empathy_os/emergence.py +21 -22
  116. empathy_os/exceptions.py +18 -30
  117. empathy_os/feedback_loops.py +30 -33
  118. empathy_os/levels.py +32 -35
  119. empathy_os/leverage_points.py +31 -32
  120. empathy_os/logging_config.py +19 -16
  121. empathy_os/memory/__init__.py +195 -0
  122. empathy_os/memory/claude_memory.py +466 -0
  123. empathy_os/memory/config.py +224 -0
  124. empathy_os/memory/control_panel.py +1298 -0
  125. empathy_os/memory/edges.py +179 -0
  126. empathy_os/memory/graph.py +567 -0
  127. empathy_os/memory/long_term.py +1194 -0
  128. empathy_os/memory/nodes.py +179 -0
  129. empathy_os/memory/redis_bootstrap.py +540 -0
  130. empathy_os/memory/security/__init__.py +31 -0
  131. empathy_os/memory/security/audit_logger.py +930 -0
  132. empathy_os/memory/security/pii_scrubber.py +640 -0
  133. empathy_os/memory/security/secrets_detector.py +678 -0
  134. empathy_os/memory/short_term.py +2119 -0
  135. empathy_os/memory/storage/__init__.py +15 -0
  136. empathy_os/memory/summary_index.py +583 -0
  137. empathy_os/memory/unified.py +619 -0
  138. empathy_os/metrics/__init__.py +12 -0
  139. empathy_os/metrics/prompt_metrics.py +190 -0
  140. empathy_os/models/__init__.py +136 -0
  141. empathy_os/models/__main__.py +13 -0
  142. empathy_os/models/cli.py +655 -0
  143. empathy_os/models/empathy_executor.py +354 -0
  144. empathy_os/models/executor.py +252 -0
  145. empathy_os/models/fallback.py +671 -0
  146. empathy_os/models/provider_config.py +563 -0
  147. empathy_os/models/registry.py +382 -0
  148. empathy_os/models/tasks.py +302 -0
  149. empathy_os/models/telemetry.py +548 -0
  150. empathy_os/models/token_estimator.py +378 -0
  151. empathy_os/models/validation.py +274 -0
  152. empathy_os/monitoring/__init__.py +52 -0
  153. empathy_os/monitoring/alerts.py +23 -0
  154. empathy_os/monitoring/alerts_cli.py +268 -0
  155. empathy_os/monitoring/multi_backend.py +271 -0
  156. empathy_os/monitoring/otel_backend.py +363 -0
  157. empathy_os/optimization/__init__.py +19 -0
  158. empathy_os/optimization/context_optimizer.py +272 -0
  159. empathy_os/pattern_library.py +30 -29
  160. empathy_os/persistence.py +35 -37
  161. empathy_os/platform_utils.py +261 -0
  162. empathy_os/plugins/__init__.py +28 -0
  163. empathy_os/plugins/base.py +361 -0
  164. empathy_os/plugins/registry.py +268 -0
  165. empathy_os/project_index/__init__.py +30 -0
  166. empathy_os/project_index/cli.py +335 -0
  167. empathy_os/project_index/crew_integration.py +430 -0
  168. empathy_os/project_index/index.py +425 -0
  169. empathy_os/project_index/models.py +501 -0
  170. empathy_os/project_index/reports.py +473 -0
  171. empathy_os/project_index/scanner.py +538 -0
  172. empathy_os/prompts/__init__.py +61 -0
  173. empathy_os/prompts/config.py +77 -0
  174. empathy_os/prompts/context.py +177 -0
  175. empathy_os/prompts/parser.py +285 -0
  176. empathy_os/prompts/registry.py +313 -0
  177. empathy_os/prompts/templates.py +208 -0
  178. empathy_os/redis_config.py +144 -58
  179. empathy_os/redis_memory.py +79 -77
  180. empathy_os/resilience/__init__.py +56 -0
  181. empathy_os/resilience/circuit_breaker.py +256 -0
  182. empathy_os/resilience/fallback.py +179 -0
  183. empathy_os/resilience/health.py +300 -0
  184. empathy_os/resilience/retry.py +209 -0
  185. empathy_os/resilience/timeout.py +135 -0
  186. empathy_os/routing/__init__.py +43 -0
  187. empathy_os/routing/chain_executor.py +433 -0
  188. empathy_os/routing/classifier.py +217 -0
  189. empathy_os/routing/smart_router.py +234 -0
  190. empathy_os/routing/wizard_registry.py +307 -0
  191. empathy_os/templates.py +19 -14
  192. empathy_os/trust/__init__.py +28 -0
  193. empathy_os/trust/circuit_breaker.py +579 -0
  194. empathy_os/trust_building.py +67 -58
  195. empathy_os/validation/__init__.py +19 -0
  196. empathy_os/validation/xml_validator.py +281 -0
  197. empathy_os/wizard_factory_cli.py +170 -0
  198. empathy_os/{workflows.py → workflow_commands.py} +131 -37
  199. empathy_os/workflows/__init__.py +360 -0
  200. empathy_os/workflows/base.py +1660 -0
  201. empathy_os/workflows/bug_predict.py +962 -0
  202. empathy_os/workflows/code_review.py +960 -0
  203. empathy_os/workflows/code_review_adapters.py +310 -0
  204. empathy_os/workflows/code_review_pipeline.py +720 -0
  205. empathy_os/workflows/config.py +600 -0
  206. empathy_os/workflows/dependency_check.py +648 -0
  207. empathy_os/workflows/document_gen.py +1069 -0
  208. empathy_os/workflows/documentation_orchestrator.py +1205 -0
  209. empathy_os/workflows/health_check.py +679 -0
  210. empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
  211. empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
  212. empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
  213. empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
  214. empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
  215. empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
  216. empathy_os/workflows/manage_documentation.py +804 -0
  217. empathy_os/workflows/new_sample_workflow1.py +146 -0
  218. empathy_os/workflows/new_sample_workflow1_README.md +150 -0
  219. empathy_os/workflows/perf_audit.py +687 -0
  220. empathy_os/workflows/pr_review.py +748 -0
  221. empathy_os/workflows/progress.py +445 -0
  222. empathy_os/workflows/progress_server.py +322 -0
  223. empathy_os/workflows/refactor_plan.py +693 -0
  224. empathy_os/workflows/release_prep.py +808 -0
  225. empathy_os/workflows/research_synthesis.py +404 -0
  226. empathy_os/workflows/secure_release.py +585 -0
  227. empathy_os/workflows/security_adapters.py +297 -0
  228. empathy_os/workflows/security_audit.py +1046 -0
  229. empathy_os/workflows/step_config.py +234 -0
  230. empathy_os/workflows/test5.py +125 -0
  231. empathy_os/workflows/test5_README.md +158 -0
  232. empathy_os/workflows/test_gen.py +1855 -0
  233. empathy_os/workflows/test_lifecycle.py +526 -0
  234. empathy_os/workflows/test_maintenance.py +626 -0
  235. empathy_os/workflows/test_maintenance_cli.py +590 -0
  236. empathy_os/workflows/test_maintenance_crew.py +821 -0
  237. empathy_os/workflows/xml_enhanced_crew.py +285 -0
  238. empathy_software_plugin/__init__.py +1 -2
  239. empathy_software_plugin/cli/__init__.py +120 -0
  240. empathy_software_plugin/cli/inspect.py +362 -0
  241. empathy_software_plugin/cli.py +49 -27
  242. empathy_software_plugin/plugin.py +4 -8
  243. empathy_software_plugin/wizards/__init__.py +42 -0
  244. empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
  245. empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
  246. empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
  247. empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
  248. empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
  249. empathy_software_plugin/wizards/base_wizard.py +288 -0
  250. empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
  251. empathy_software_plugin/wizards/code_review_wizard.py +606 -0
  252. empathy_software_plugin/wizards/debugging/__init__.py +50 -0
  253. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
  254. empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
  255. empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
  256. empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
  257. empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
  258. empathy_software_plugin/wizards/debugging/verification.py +369 -0
  259. empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
  260. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
  261. empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
  262. empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
  263. empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
  264. empathy_software_plugin/wizards/performance/__init__.py +9 -0
  265. empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
  266. empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
  267. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
  268. empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
  269. empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
  270. empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
  271. empathy_software_plugin/wizards/security/__init__.py +32 -0
  272. empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
  273. empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
  274. empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
  275. empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
  276. empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
  277. empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
  278. empathy_software_plugin/wizards/testing/__init__.py +27 -0
  279. empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
  280. empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
  281. empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
  282. empathy_software_plugin/wizards/testing_wizard.py +274 -0
  283. hot_reload/README.md +473 -0
  284. hot_reload/__init__.py +62 -0
  285. hot_reload/config.py +84 -0
  286. hot_reload/integration.py +228 -0
  287. hot_reload/reloader.py +298 -0
  288. hot_reload/watcher.py +179 -0
  289. hot_reload/websocket.py +176 -0
  290. scaffolding/README.md +589 -0
  291. scaffolding/__init__.py +35 -0
  292. scaffolding/__main__.py +14 -0
  293. scaffolding/cli.py +240 -0
  294. test_generator/__init__.py +38 -0
  295. test_generator/__main__.py +14 -0
  296. test_generator/cli.py +226 -0
  297. test_generator/generator.py +325 -0
  298. test_generator/risk_analyzer.py +216 -0
  299. workflow_patterns/__init__.py +33 -0
  300. workflow_patterns/behavior.py +249 -0
  301. workflow_patterns/core.py +76 -0
  302. workflow_patterns/output.py +99 -0
  303. workflow_patterns/registry.py +255 -0
  304. workflow_patterns/structural.py +288 -0
  305. workflow_scaffolding/__init__.py +11 -0
  306. workflow_scaffolding/__main__.py +12 -0
  307. workflow_scaffolding/cli.py +206 -0
  308. workflow_scaffolding/generator.py +265 -0
  309. agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
  310. agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
  311. agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
  312. agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
  313. agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
  314. agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
  315. agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
  316. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
  317. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
  318. agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
  319. agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
  320. agents/compliance_anticipation_agent.py +0 -1427
  321. agents/epic_integration_wizard.py +0 -541
  322. agents/trust_building_behaviors.py +0 -891
  323. empathy_framework-2.4.0.dist-info/METADATA +0 -485
  324. empathy_framework-2.4.0.dist-info/RECORD +0 -102
  325. empathy_framework-2.4.0.dist-info/entry_points.txt +0 -6
  326. empathy_llm_toolkit/htmlcov/status.json +0 -1
  327. empathy_llm_toolkit/security/htmlcov/status.json +0 -1
  328. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/WHEEL +0 -0
  329. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,454 @@
1
+ """CrewAI Adapter
2
+
3
+ Creates agents using CrewAI's role/goal/backstory pattern while integrating
4
+ with Empathy's cost optimization and pattern learning.
5
+
6
+ CrewAI is a multi-agent framework focusing on:
7
+ - Role-based agents with goals and backstories
8
+ - Hierarchical and sequential crew orchestration
9
+ - Task delegation and collaboration
10
+
11
+ Requires: pip install crewai
12
+
13
+ Copyright 2025 Smart-AI-Memory
14
+ Licensed under Fair Source License 0.9
15
+ """
16
+
17
+ import asyncio
18
+ import os
19
+ from collections.abc import Callable
20
+ from typing import Any
21
+
22
+ from empathy_llm_toolkit.agent_factory.base import (
23
+ AgentConfig,
24
+ AgentRole,
25
+ BaseAdapter,
26
+ BaseAgent,
27
+ BaseWorkflow,
28
+ WorkflowConfig,
29
+ )
30
+
31
+ # Lazy imports for CrewAI
32
+ _crewai_available = None
33
+
34
+
35
+ def _check_crewai():
36
+ """Check if CrewAI is available."""
37
+ global _crewai_available
38
+ if _crewai_available is None:
39
+ try:
40
+ import crewai # noqa: F401
41
+
42
+ _crewai_available = True
43
+ except ImportError:
44
+ _crewai_available = False
45
+ return _crewai_available
46
+
47
+
48
+ class CrewAIAgent(BaseAgent):
49
+ """Agent wrapping a CrewAI Agent."""
50
+
51
+ def __init__(self, config: AgentConfig, crewai_agent=None):
52
+ """Initialize CrewAI agent wrapper.
53
+
54
+ Args:
55
+ config: Agent configuration
56
+ crewai_agent: The underlying CrewAI Agent instance
57
+
58
+ """
59
+ super().__init__(config)
60
+ self._crewai_agent = crewai_agent
61
+
62
+ async def invoke(self, input_data: str | dict, context: dict | None = None) -> dict:
63
+ """Invoke the CrewAI agent.
64
+
65
+ CrewAI agents work within crews/tasks, so we create a temporary
66
+ task for standalone invocation.
67
+ """
68
+ if not self._crewai_agent:
69
+ return {"output": "No CrewAI agent configured", "metadata": {}}
70
+
71
+ try:
72
+ from crewai import Task
73
+
74
+ # Format input as task description
75
+ if isinstance(input_data, str):
76
+ description = input_data
77
+ else:
78
+ description = input_data.get("task", input_data.get("input", str(input_data)))
79
+
80
+ # Add context to description if provided
81
+ if context:
82
+ context_str = "\n".join(f"{k}: {v}" for k, v in context.items())
83
+ description = f"{description}\n\nContext:\n{context_str}"
84
+
85
+ # Create and execute task
86
+ task = Task(
87
+ description=description,
88
+ expected_output="A comprehensive response addressing the task.",
89
+ agent=self._crewai_agent,
90
+ )
91
+
92
+ # CrewAI is primarily sync, so run in executor
93
+ loop = asyncio.get_event_loop()
94
+ result = await loop.run_in_executor(None, self._execute_task, task)
95
+
96
+ output = str(result) if result else "Task completed"
97
+
98
+ # Track conversation
99
+ self._conversation_history.append({"role": "user", "content": description})
100
+ self._conversation_history.append({"role": "assistant", "content": output})
101
+
102
+ return {
103
+ "output": output,
104
+ "metadata": {
105
+ "model": self.model,
106
+ "framework": "crewai",
107
+ "agent_role": self._crewai_agent.role if self._crewai_agent else None,
108
+ },
109
+ }
110
+
111
+ except Exception as e:
112
+ return {
113
+ "output": f"Error: {e!s}",
114
+ "metadata": {"error": str(e), "framework": "crewai"},
115
+ }
116
+
117
+ def _execute_task(self, task):
118
+ """Execute a CrewAI task synchronously."""
119
+ try:
120
+ # In newer versions of CrewAI, tasks are executed via Crew
121
+ # For standalone execution, we use the agent's execute_task method
122
+ if hasattr(task, "execute"):
123
+ return task.execute()
124
+ if hasattr(self._crewai_agent, "execute_task"):
125
+ return self._crewai_agent.execute_task(task)
126
+ # Fallback: create minimal crew
127
+ from crewai import Crew
128
+
129
+ crew = Crew(agents=[self._crewai_agent], tasks=[task], verbose=False)
130
+ return crew.kickoff()
131
+ except Exception as e:
132
+ return f"Task execution error: {e}"
133
+
134
+ async def stream(self, input_data: str | dict, context: dict | None = None):
135
+ """Stream CrewAI response.
136
+
137
+ Note: CrewAI doesn't natively support streaming, so we simulate
138
+ by yielding the complete response.
139
+ """
140
+ result = await self.invoke(input_data, context)
141
+ yield result
142
+
143
+ @property
144
+ def crewai_agent(self):
145
+ """Get the underlying CrewAI agent."""
146
+ return self._crewai_agent
147
+
148
+
149
+ class CrewAIWorkflow(BaseWorkflow):
150
+ """Workflow using CrewAI's Crew orchestration."""
151
+
152
+ def __init__(self, config: WorkflowConfig, agents: list[BaseAgent], crew=None):
153
+ """Initialize CrewAI workflow.
154
+
155
+ Args:
156
+ config: Workflow configuration
157
+ agents: List of CrewAIAgent instances
158
+ crew: Optional pre-built CrewAI Crew instance
159
+
160
+ """
161
+ super().__init__(config, agents)
162
+ self._crew = crew
163
+ self._tasks: list = []
164
+
165
+ async def run(self, input_data: str | dict, initial_state: dict | None = None) -> dict:
166
+ """Run the CrewAI crew workflow."""
167
+ self._state = initial_state or {}
168
+
169
+ if not self._crew:
170
+ return {"output": "No CrewAI Crew configured", "error": "Missing crew"}
171
+
172
+ try:
173
+ # Format input
174
+ if isinstance(input_data, str):
175
+ inputs = {"input": input_data}
176
+ else:
177
+ inputs = dict(input_data)
178
+
179
+ # Add state to inputs
180
+ inputs.update(self._state)
181
+
182
+ # Run crew in executor (CrewAI is sync)
183
+ loop = asyncio.get_event_loop()
184
+ result = await loop.run_in_executor(None, self._crew.kickoff, inputs)
185
+
186
+ output = str(result) if result else "Crew completed"
187
+
188
+ return {
189
+ "output": output,
190
+ "results": [{"crew_result": str(result)}],
191
+ "state": self._state,
192
+ "metadata": {"framework": "crewai"},
193
+ }
194
+
195
+ except Exception as e:
196
+ return {
197
+ "output": f"Crew execution error: {e}",
198
+ "error": str(e),
199
+ "state": self._state,
200
+ }
201
+
202
+ async def stream(self, input_data: str | dict, initial_state: dict | None = None):
203
+ """Stream workflow execution.
204
+
205
+ Note: CrewAI doesn't support streaming, so we yield progress updates.
206
+ """
207
+ yield {"event": "crew_start", "crew": self.config.name}
208
+
209
+ result = await self.run(input_data, initial_state)
210
+
211
+ yield {"event": "crew_end", "result": result}
212
+
213
+ def add_task(self, description: str, expected_output: str, agent_name: str) -> None:
214
+ """Add a task to the workflow.
215
+
216
+ Args:
217
+ description: Task description
218
+ expected_output: Expected output description
219
+ agent_name: Name of agent to assign task to
220
+
221
+ """
222
+ if not _check_crewai():
223
+ return
224
+
225
+ from crewai import Task
226
+
227
+ agent = self.agents.get(agent_name)
228
+ if agent and hasattr(agent, "crewai_agent"):
229
+ task = Task(
230
+ description=description,
231
+ expected_output=expected_output,
232
+ agent=agent.crewai_agent,
233
+ )
234
+ self._tasks.append(task)
235
+
236
+
237
+ class CrewAIAdapter(BaseAdapter):
238
+ """Adapter for CrewAI framework."""
239
+
240
+ def __init__(self, provider: str = "openai", api_key: str | None = None):
241
+ """Initialize CrewAI adapter.
242
+
243
+ Args:
244
+ provider: LLM provider (openai is default for CrewAI)
245
+ api_key: API key (uses env var if not provided)
246
+
247
+ """
248
+ self.provider = provider
249
+ self.api_key = api_key or os.getenv(
250
+ "OPENAI_API_KEY" if provider == "openai" else "ANTHROPIC_API_KEY",
251
+ )
252
+
253
+ @property
254
+ def framework_name(self) -> str:
255
+ return "crewai"
256
+
257
+ def is_available(self) -> bool:
258
+ """Check if CrewAI is installed."""
259
+ return bool(_check_crewai())
260
+
261
+ def create_agent(self, config: AgentConfig) -> CrewAIAgent:
262
+ """Create a CrewAI-based agent."""
263
+ if not self.is_available():
264
+ raise ImportError("CrewAI not installed. Run: pip install crewai")
265
+
266
+ from crewai import Agent
267
+
268
+ # Map Empathy role to CrewAI role string
269
+ role = self._map_role(config.role)
270
+
271
+ # Generate goal based on role and description
272
+ goal = config.description or self._default_goal(config.role)
273
+
274
+ # Generate backstory from system prompt or role
275
+ backstory = config.system_prompt or self._default_backstory(config.role)
276
+
277
+ # Convert tools to CrewAI format
278
+ crewai_tools = [self._convert_tool(t) for t in config.tools if t]
279
+ crewai_tools = [t for t in crewai_tools if t is not None]
280
+
281
+ # Create CrewAI agent
282
+ crewai_agent = Agent(
283
+ role=role,
284
+ goal=goal,
285
+ backstory=backstory,
286
+ tools=crewai_tools if crewai_tools else None,
287
+ verbose=False,
288
+ allow_delegation=config.role == AgentRole.COORDINATOR,
289
+ )
290
+
291
+ return CrewAIAgent(config, crewai_agent)
292
+
293
+ def create_workflow(self, config: WorkflowConfig, agents: list[BaseAgent]) -> CrewAIWorkflow:
294
+ """Create a CrewAI Crew workflow."""
295
+ if not self.is_available():
296
+ raise ImportError("CrewAI not installed")
297
+
298
+ from crewai import Crew, Process
299
+
300
+ # Determine process type from workflow mode
301
+ if config.mode == "hierarchical":
302
+ process = Process.hierarchical
303
+ else:
304
+ process = Process.sequential
305
+
306
+ # Extract CrewAI agents from wrappers
307
+ crewai_agents = []
308
+ for agent in agents:
309
+ if isinstance(agent, CrewAIAgent) and agent.crewai_agent:
310
+ crewai_agents.append(agent.crewai_agent)
311
+
312
+ if not crewai_agents:
313
+ return CrewAIWorkflow(config, agents)
314
+
315
+ # Create Crew
316
+ crew = Crew(
317
+ agents=crewai_agents,
318
+ tasks=[], # Tasks will be added dynamically or via add_task
319
+ process=process,
320
+ verbose=False,
321
+ )
322
+
323
+ return CrewAIWorkflow(config, agents, crew)
324
+
325
+ def create_tool(
326
+ self,
327
+ name: str,
328
+ description: str,
329
+ func: Callable,
330
+ args_schema: dict | None = None,
331
+ ) -> Any:
332
+ """Create a CrewAI tool."""
333
+ if not self.is_available():
334
+ return super().create_tool(name, description, func, args_schema)
335
+
336
+ try:
337
+ from crewai.tools import BaseTool
338
+
339
+ # Create dynamic tool class
340
+ class DynamicTool(BaseTool):
341
+ name: str = name
342
+ description: str = description
343
+
344
+ def _run(self, **kwargs) -> str:
345
+ return str(func(**kwargs))
346
+
347
+ return DynamicTool()
348
+ except ImportError:
349
+ # Fallback to dict format
350
+ return {"name": name, "description": description, "func": func}
351
+
352
+ def _convert_tool(self, tool: Any) -> Any:
353
+ """Convert a tool to CrewAI format."""
354
+ if not self.is_available():
355
+ return None
356
+
357
+ # If already a CrewAI tool, return as-is
358
+ try:
359
+ from crewai.tools import BaseTool
360
+
361
+ if isinstance(tool, BaseTool):
362
+ return tool
363
+ except ImportError:
364
+ pass
365
+
366
+ # If dict, convert to CrewAI tool
367
+ if isinstance(tool, dict):
368
+ return self.create_tool(
369
+ name=tool.get("name", "tool"),
370
+ description=tool.get("description", ""),
371
+ func=tool.get("func", lambda: None),
372
+ args_schema=tool.get("args_schema"),
373
+ )
374
+
375
+ return None
376
+
377
+ def _map_role(self, role: AgentRole) -> str:
378
+ """Map Empathy AgentRole to CrewAI role string."""
379
+ role_map = {
380
+ AgentRole.COORDINATOR: "Project Manager",
381
+ AgentRole.RESEARCHER: "Senior Researcher",
382
+ AgentRole.WRITER: "Content Writer",
383
+ AgentRole.REVIEWER: "Quality Reviewer",
384
+ AgentRole.EDITOR: "Editor",
385
+ AgentRole.EXECUTOR: "Task Executor",
386
+ AgentRole.DEBUGGER: "Software Debugger",
387
+ AgentRole.SECURITY: "Security Analyst",
388
+ AgentRole.ARCHITECT: "Software Architect",
389
+ AgentRole.TESTER: "QA Tester",
390
+ AgentRole.DOCUMENTER: "Technical Writer",
391
+ AgentRole.RETRIEVER: "Information Retriever",
392
+ AgentRole.SUMMARIZER: "Content Summarizer",
393
+ AgentRole.ANSWERER: "Question Answerer",
394
+ AgentRole.CUSTOM: "Specialist",
395
+ }
396
+ return role_map.get(role, "Specialist")
397
+
398
+ def _default_goal(self, role: AgentRole) -> str:
399
+ """Generate default goal based on role."""
400
+ goal_map = {
401
+ AgentRole.COORDINATOR: "Coordinate team efforts and ensure project success",
402
+ AgentRole.RESEARCHER: "Conduct thorough research and gather comprehensive information",
403
+ AgentRole.WRITER: "Create clear, engaging, and high-quality content",
404
+ AgentRole.REVIEWER: "Provide constructive feedback and ensure quality standards",
405
+ AgentRole.EDITOR: "Refine and improve content for clarity and impact",
406
+ AgentRole.EXECUTOR: "Execute tasks efficiently and report results accurately",
407
+ AgentRole.DEBUGGER: "Identify and resolve software bugs systematically",
408
+ AgentRole.SECURITY: "Analyze systems for security vulnerabilities",
409
+ AgentRole.ARCHITECT: "Design robust and scalable system architectures",
410
+ AgentRole.TESTER: "Create comprehensive tests and ensure software quality",
411
+ AgentRole.DOCUMENTER: "Create clear and comprehensive documentation",
412
+ AgentRole.RETRIEVER: "Retrieve relevant information from knowledge bases",
413
+ AgentRole.SUMMARIZER: "Create concise and accurate summaries",
414
+ AgentRole.ANSWERER: "Provide accurate answers to questions",
415
+ AgentRole.CUSTOM: "Complete assigned tasks with excellence",
416
+ }
417
+ return goal_map.get(role, "Complete assigned tasks with excellence")
418
+
419
+ def _default_backstory(self, role: AgentRole) -> str:
420
+ """Generate default backstory based on role."""
421
+ backstory_map = {
422
+ AgentRole.COORDINATOR: (
423
+ "You are an experienced project manager with a track record of "
424
+ "successfully coordinating complex projects and diverse teams."
425
+ ),
426
+ AgentRole.RESEARCHER: (
427
+ "You are a meticulous researcher with expertise in finding "
428
+ "reliable information and synthesizing complex topics."
429
+ ),
430
+ AgentRole.WRITER: (
431
+ "You are a skilled writer with years of experience crafting "
432
+ "compelling narratives and clear technical content."
433
+ ),
434
+ AgentRole.REVIEWER: (
435
+ "You are a seasoned reviewer known for your attention to detail "
436
+ "and constructive feedback that improves quality."
437
+ ),
438
+ AgentRole.DEBUGGER: (
439
+ "You are an expert debugger with deep knowledge of software systems "
440
+ "and a systematic approach to problem-solving."
441
+ ),
442
+ AgentRole.SECURITY: (
443
+ "You are a security analyst with expertise in identifying "
444
+ "vulnerabilities and recommending protective measures."
445
+ ),
446
+ AgentRole.ARCHITECT: (
447
+ "You are a software architect with experience designing "
448
+ "scalable, maintainable systems for enterprise applications."
449
+ ),
450
+ }
451
+ return backstory_map.get(
452
+ role,
453
+ f"You are an experienced professional excelling as a {role.value}.",
454
+ )